Rollup merge of #143698 - benschulz:unused-parens-2, r=lcnr,compiler-errors
Fix unused_parens false positive
Resolves rust-lang/rust#143653.
The "no bounds exception" was indiscriminately set to `OneBound` for referents and pointees. However, if the reference or pointer type itself appears in no-bounds position, any constraints it has must be propagated.
```rust
// unused parens: not in no-bounds position
fn foo(_: Box<(dyn Send)>) {}
// unused parens: in no-bounds position, but one-bound exception applies
fn bar(_: Box<dyn Fn(&u32) -> &(dyn Send)>) {}
// *NOT* unused parens: in no-bounds position, but no exceptions to be made
fn baz(_: Box<dyn Fn(&u32) -> &(dyn Send) + Send>) {}
```
diff --git a/Cargo.lock b/Cargo.lock
index b7fc2de..0d37e8b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4563,7 +4563,10 @@
"rustc_macros",
"rustc_serialize",
"rustc_span",
+ "serde",
+ "serde_derive",
"serde_json",
+ "serde_path_to_error",
"tracing",
]
@@ -4956,6 +4959,16 @@
]
[[package]]
+name = "serde_path_to_error"
+version = "0.1.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
+dependencies = [
+ "itoa",
+ "serde",
+]
+
+[[package]]
name = "serde_spanned"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index 80b44e4..716bb71 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -313,7 +313,6 @@ pub fn layout_of_struct_or_enum<
scalar_valid_range: (Bound<u128>, Bound<u128>),
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
- dont_niche_optimize_enum: bool,
always_sized: bool,
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
let (present_first, present_second) = {
@@ -352,13 +351,7 @@ pub fn layout_of_struct_or_enum<
// structs. (We have also handled univariant enums
// that allow representation optimization.)
assert!(is_enum);
- self.layout_of_enum(
- repr,
- variants,
- discr_range_of_repr,
- discriminants,
- dont_niche_optimize_enum,
- )
+ self.layout_of_enum(repr, variants, discr_range_of_repr, discriminants)
}
}
@@ -599,7 +592,6 @@ fn layout_of_enum<
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
- dont_niche_optimize_enum: bool,
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
// Until we've decided whether to use the tagged or
// niche filling LayoutData, we don't want to intern the
@@ -618,7 +610,7 @@ struct TmpLayout<FieldIdx: Idx, VariantIdx: Idx> {
}
let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx, VariantIdx>> {
- if dont_niche_optimize_enum {
+ if repr.inhibit_enum_layout_opt() {
return None;
}
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 5bd7350..8e34670 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1376,6 +1376,28 @@ pub fn contains(&self, v: u128) -> bool {
}
}
+ /// Returns `true` if all the values in `other` are contained in this range,
+ /// when the values are considered as having width `size`.
+ #[inline(always)]
+ pub fn contains_range(&self, other: Self, size: Size) -> bool {
+ if self.is_full_for(size) {
+ true
+ } else {
+ let trunc = |x| size.truncate(x);
+
+ let delta = self.start;
+ let max = trunc(self.end.wrapping_sub(delta));
+
+ let other_start = trunc(other.start.wrapping_sub(delta));
+ let other_end = trunc(other.end.wrapping_sub(delta));
+
+ // Having shifted both input ranges by `delta`, now we only need to check
+ // whether `0..=max` contains `other_start..=other_end`, which can only
+ // happen if the other doesn't wrap since `self` isn't everything.
+ (other_start <= other_end) && (other_end <= max)
+ }
+ }
+
/// Returns `self` with replaced `start`
#[inline(always)]
fn with_start(mut self, start: u128) -> Self {
diff --git a/compiler/rustc_abi/src/tests.rs b/compiler/rustc_abi/src/tests.rs
index d993012..d49c2d4 100644
--- a/compiler/rustc_abi/src/tests.rs
+++ b/compiler/rustc_abi/src/tests.rs
@@ -5,3 +5,66 @@ fn align_constants() {
assert_eq!(Align::ONE, Align::from_bytes(1).unwrap());
assert_eq!(Align::EIGHT, Align::from_bytes(8).unwrap());
}
+
+#[test]
+fn wrapping_range_contains_range() {
+ let size16 = Size::from_bytes(16);
+
+ let a = WrappingRange { start: 10, end: 20 };
+ assert!(a.contains_range(a, size16));
+ assert!(a.contains_range(WrappingRange { start: 11, end: 19 }, size16));
+ assert!(a.contains_range(WrappingRange { start: 10, end: 10 }, size16));
+ assert!(a.contains_range(WrappingRange { start: 20, end: 20 }, size16));
+ assert!(!a.contains_range(WrappingRange { start: 10, end: 21 }, size16));
+ assert!(!a.contains_range(WrappingRange { start: 9, end: 20 }, size16));
+ assert!(!a.contains_range(WrappingRange { start: 4, end: 6 }, size16));
+ assert!(!a.contains_range(WrappingRange { start: 24, end: 26 }, size16));
+
+ assert!(!a.contains_range(WrappingRange { start: 16, end: 14 }, size16));
+
+ let b = WrappingRange { start: 20, end: 10 };
+ assert!(b.contains_range(b, size16));
+ assert!(b.contains_range(WrappingRange { start: 20, end: 20 }, size16));
+ assert!(b.contains_range(WrappingRange { start: 10, end: 10 }, size16));
+ assert!(b.contains_range(WrappingRange { start: 0, end: 10 }, size16));
+ assert!(b.contains_range(WrappingRange { start: 20, end: 30 }, size16));
+ assert!(b.contains_range(WrappingRange { start: 20, end: 9 }, size16));
+ assert!(b.contains_range(WrappingRange { start: 21, end: 10 }, size16));
+ assert!(b.contains_range(WrappingRange { start: 999, end: 9999 }, size16));
+ assert!(b.contains_range(WrappingRange { start: 999, end: 9 }, size16));
+ assert!(!b.contains_range(WrappingRange { start: 19, end: 19 }, size16));
+ assert!(!b.contains_range(WrappingRange { start: 11, end: 11 }, size16));
+ assert!(!b.contains_range(WrappingRange { start: 19, end: 11 }, size16));
+ assert!(!b.contains_range(WrappingRange { start: 11, end: 19 }, size16));
+
+ let f = WrappingRange { start: 0, end: u128::MAX };
+ assert!(f.contains_range(WrappingRange { start: 10, end: 20 }, size16));
+ assert!(f.contains_range(WrappingRange { start: 20, end: 10 }, size16));
+
+ let g = WrappingRange { start: 2, end: 1 };
+ assert!(g.contains_range(WrappingRange { start: 10, end: 20 }, size16));
+ assert!(g.contains_range(WrappingRange { start: 20, end: 10 }, size16));
+
+ let size1 = Size::from_bytes(1);
+ let u8r = WrappingRange { start: 0, end: 255 };
+ let i8r = WrappingRange { start: 128, end: 127 };
+ assert!(u8r.contains_range(i8r, size1));
+ assert!(i8r.contains_range(u8r, size1));
+ assert!(!u8r.contains_range(i8r, size16));
+ assert!(i8r.contains_range(u8r, size16));
+
+ let boolr = WrappingRange { start: 0, end: 1 };
+ assert!(u8r.contains_range(boolr, size1));
+ assert!(i8r.contains_range(boolr, size1));
+ assert!(!boolr.contains_range(u8r, size1));
+ assert!(!boolr.contains_range(i8r, size1));
+
+ let cmpr = WrappingRange { start: 255, end: 1 };
+ assert!(u8r.contains_range(cmpr, size1));
+ assert!(i8r.contains_range(cmpr, size1));
+ assert!(!cmpr.contains_range(u8r, size1));
+ assert!(!cmpr.contains_range(i8r, size1));
+
+ assert!(!boolr.contains_range(cmpr, size1));
+ assert!(cmpr.contains_range(boolr, size1));
+}
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 97e0709..984b280 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2849,7 +2849,7 @@ pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
}
}
-#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable)]
+#[derive(Clone, Copy, Encodable, Decodable, Debug, HashStable_Generic, Walkable, PartialEq, Eq)]
pub enum AsmMacro {
/// The `asm!` macro
Asm,
diff --git a/compiler/rustc_attr_parsing/src/attributes/stability.rs b/compiler/rustc_attr_parsing/src/attributes/stability.rs
index 5933774..c54fc6b 100644
--- a/compiler/rustc_attr_parsing/src/attributes/stability.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/stability.rs
@@ -74,8 +74,15 @@ impl<S: Stage> AttributeParser<S> for StabilityParser {
template!(NameValueStr: "deprecation message"),
|this, cx, args| {
reject_outside_std!(cx);
- this.allowed_through_unstable_modules =
- args.name_value().and_then(|i| i.value_as_str())
+ let Some(nv) = args.name_value() else {
+ cx.expected_name_value(cx.attr_span, None);
+ return;
+ };
+ let Some(value_str) = nv.value_as_str() else {
+ cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
+ return;
+ };
+ this.allowed_through_unstable_modules = Some(value_str);
},
),
];
@@ -247,7 +254,12 @@ pub(crate) fn parse_stability<S: Stage>(
let mut feature = None;
let mut since = None;
- for param in args.list()?.mixed() {
+ let ArgParser::List(list) = args else {
+ cx.expected_list(cx.attr_span);
+ return None;
+ };
+
+ for param in list.mixed() {
let param_span = param.span();
let Some(param) = param.meta_item() else {
cx.emit_err(session_diagnostics::UnsupportedLiteral {
@@ -322,7 +334,13 @@ pub(crate) fn parse_unstability<S: Stage>(
let mut is_soft = false;
let mut implied_by = None;
let mut old_name = None;
- for param in args.list()?.mixed() {
+
+ let ArgParser::List(list) = args else {
+ cx.expected_list(cx.attr_span);
+ return None;
+ };
+
+ for param in list.mixed() {
let Some(param) = param.meta_item() else {
cx.emit_err(session_diagnostics::UnsupportedLiteral {
span: param.span(),
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 447bf7d..a5661e4 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -115,10 +115,8 @@ fn group_move_errors(&mut self) -> Vec<GroupedMoveError<'tcx>> {
fn append_to_grouped_errors(
&self,
grouped_errors: &mut Vec<GroupedMoveError<'tcx>>,
- error: MoveError<'tcx>,
+ MoveError { place: original_path, location, kind }: MoveError<'tcx>,
) {
- let MoveError { place: original_path, location, kind } = error;
-
// Note: that the only time we assign a place isn't a temporary
// to a user variable is when initializing it.
// If that ever stops being the case, then the ever initialized
@@ -251,54 +249,47 @@ fn append_binding_error(
}
fn report(&mut self, error: GroupedMoveError<'tcx>) {
- let (mut err, err_span) = {
- let (span, use_spans, original_path, kind) = match error {
- GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
- | GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
- (span, None, original_path, kind)
- }
- GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
- (use_spans.args_or_use(), Some(use_spans), original_path, kind)
- }
- };
- debug!(
- "report: original_path={:?} span={:?}, kind={:?} \
- original_path.is_upvar_field_projection={:?}",
- original_path,
- span,
- kind,
- self.is_upvar_field_projection(original_path.as_ref())
- );
- if self.has_ambiguous_copy(original_path.ty(self.body, self.infcx.tcx).ty) {
- // If the type may implement Copy, skip the error.
- // It's an error with the Copy implementation (e.g. duplicate Copy) rather than borrow check
- self.dcx().span_delayed_bug(
- span,
- "Type may implement copy, but there is no other error.",
- );
- return;
+ let (span, use_spans, original_path, kind) = match error {
+ GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. }
+ | GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => {
+ (span, None, original_path, kind)
}
- (
- match kind {
- &IllegalMoveOriginKind::BorrowedContent { target_place } => self
- .report_cannot_move_from_borrowed_content(
- original_path,
- target_place,
- span,
- use_spans,
- ),
- &IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
- self.cannot_move_out_of_interior_of_drop(span, ty)
- }
- &IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
- self.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index))
- }
- },
- span,
- )
+ GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => {
+ (use_spans.args_or_use(), Some(use_spans), original_path, kind)
+ }
+ };
+ debug!(
+ "report: original_path={:?} span={:?}, kind={:?} \
+ original_path.is_upvar_field_projection={:?}",
+ original_path,
+ span,
+ kind,
+ self.is_upvar_field_projection(original_path.as_ref())
+ );
+ if self.has_ambiguous_copy(original_path.ty(self.body, self.infcx.tcx).ty) {
+ // If the type may implement Copy, skip the error.
+ // It's an error with the Copy implementation (e.g. duplicate Copy) rather than borrow check
+ self.dcx()
+ .span_delayed_bug(span, "Type may implement copy, but there is no other error.");
+ return;
+ }
+ let mut err = match kind {
+ &IllegalMoveOriginKind::BorrowedContent { target_place } => self
+ .report_cannot_move_from_borrowed_content(
+ original_path,
+ target_place,
+ span,
+ use_spans,
+ ),
+ &IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
+ self.cannot_move_out_of_interior_of_drop(span, ty)
+ }
+ &IllegalMoveOriginKind::InteriorOfSliceOrArray { ty, is_index } => {
+ self.cannot_move_out_of_interior_noncopy(span, ty, Some(is_index))
+ }
};
- self.add_move_hints(error, &mut err, err_span);
+ self.add_move_hints(error, &mut err, span);
self.buffer_error(err);
}
@@ -483,7 +474,8 @@ fn report_cannot_move_from_borrowed_content(
self.cannot_move_out_of_interior_noncopy(span, ty, None)
}
ty::Closure(def_id, closure_args)
- if def_id.as_local() == Some(self.mir_def_id()) && upvar_field.is_some() =>
+ if def_id.as_local() == Some(self.mir_def_id())
+ && let Some(upvar_field) = upvar_field =>
{
let closure_kind_ty = closure_args.as_closure().kind_ty();
let closure_kind = match closure_kind_ty.to_opt_closure_kind() {
@@ -496,7 +488,7 @@ fn report_cannot_move_from_borrowed_content(
let capture_description =
format!("captured variable in an `{closure_kind}` closure");
- let upvar = &self.upvars[upvar_field.unwrap().index()];
+ let upvar = &self.upvars[upvar_field.index()];
let upvar_hir_id = upvar.get_root_variable();
let upvar_name = upvar.to_string(tcx);
let upvar_span = tcx.hir_span(upvar_hir_id);
@@ -606,7 +598,7 @@ fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span
}
// No binding. Nothing to suggest.
GroupedMoveError::OtherIllegalMove { ref original_path, use_spans, .. } => {
- let use_span = use_spans.var_or_use();
+ let mut use_span = use_spans.var_or_use();
let place_ty = original_path.ty(self.body, self.infcx.tcx).ty;
let place_desc = match self.describe_place(original_path.as_ref()) {
Some(desc) => format!("`{desc}`"),
@@ -623,6 +615,36 @@ fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span
);
}
+ if let Some(upvar_field) = self
+ .prefixes(original_path.as_ref(), PrefixSet::All)
+ .find_map(|p| self.is_upvar_field_projection(p))
+ {
+ // Look for the introduction of the original binding being moved.
+ let upvar = &self.upvars[upvar_field.index()];
+ let upvar_hir_id = upvar.get_root_variable();
+ use_span = match self.infcx.tcx.parent_hir_node(upvar_hir_id) {
+ hir::Node::Param(param) => {
+ // Instead of pointing at the path where we access the value within a
+ // closure, we point at the type of the outer `fn` argument.
+ param.ty_span
+ }
+ hir::Node::LetStmt(stmt) => match (stmt.ty, stmt.init) {
+ // We point at the type of the outer let-binding.
+ (Some(ty), _) => ty.span,
+ // We point at the initializer of the outer let-binding, but only if it
+ // isn't something that spans multiple lines, like a closure, as the
+ // ASCII art gets messy.
+ (None, Some(init))
+ if !self.infcx.tcx.sess.source_map().is_multiline(init.span) =>
+ {
+ init.span
+ }
+ _ => use_span,
+ },
+ _ => use_span,
+ };
+ }
+
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: place_ty,
@@ -630,12 +652,22 @@ fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diag<'_>, span
span: use_span,
});
+ let mut pointed_at_span = false;
use_spans.args_subdiag(err, |args_span| {
+ if args_span == span || args_span == use_span {
+ pointed_at_span = true;
+ }
crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
- place: place_desc,
+ place: place_desc.clone(),
args_span,
}
});
+ if !pointed_at_span && use_span != span {
+ err.subdiagnostic(crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
+ place: place_desc,
+ args_span: span,
+ });
+ }
self.add_note_for_packed_struct_derive(err, original_path.local);
}
diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
index 74f3902..b9e0c95 100644
--- a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
@@ -4,7 +4,7 @@
use rustc_abi::Endian;
use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
-use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_hashes::Hash128;
use rustc_session::Session;
@@ -214,7 +214,7 @@ pub(super) fn create_raw_dylib_elf_stub_shared_objects<'a>(
/// It exports all the provided symbols, but is otherwise empty.
fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]) -> Vec<u8> {
use object::write::elf as write;
- use object::{Architecture, elf};
+ use object::{AddressSize, Architecture, elf};
let mut stub_buf = Vec::new();
@@ -226,47 +226,6 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
// It is important that the order of reservation matches the order of writing.
// The object crate contains many debug asserts that fire if you get this wrong.
- let endianness = match sess.target.options.endian {
- Endian::Little => object::Endianness::Little,
- Endian::Big => object::Endianness::Big,
- };
- let mut stub = write::Writer::new(endianness, true, &mut stub_buf);
-
- // These initial reservations don't reserve any bytes in the binary yet,
- // they just allocate in the internal data structures.
-
- // First, we crate the dynamic symbol table. It starts with a null symbol
- // and then all the symbols and their dynamic strings.
- stub.reserve_null_dynamic_symbol_index();
-
- let dynstrs = symbols
- .iter()
- .map(|sym| {
- stub.reserve_dynamic_symbol_index();
- (sym, stub.add_dynamic_string(sym.name.as_str().as_bytes()))
- })
- .collect::<Vec<_>>();
-
- let soname = stub.add_dynamic_string(soname.as_bytes());
-
- // Reserve the sections.
- // We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to.
- stub.reserve_shstrtab_section_index();
- let text_section_name = stub.add_section_name(".text".as_bytes());
- let text_section = stub.reserve_section_index();
- stub.reserve_dynstr_section_index();
- stub.reserve_dynsym_section_index();
- stub.reserve_dynamic_section_index();
-
- // These reservations now determine the actual layout order of the object file.
- stub.reserve_file_header();
- stub.reserve_shstrtab();
- stub.reserve_section_headers();
- stub.reserve_dynstr();
- stub.reserve_dynsym();
- stub.reserve_dynamic(2); // DT_SONAME, DT_NULL
-
- // First write the ELF header with the arch information.
let Some((arch, sub_arch)) = sess.target.object_architecture(&sess.unstable_target_features)
else {
sess.dcx().fatal(format!(
@@ -274,6 +233,87 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
sess.target.arch
));
};
+
+ let endianness = match sess.target.options.endian {
+ Endian::Little => object::Endianness::Little,
+ Endian::Big => object::Endianness::Big,
+ };
+
+ let is_64 = match arch.address_size() {
+ Some(AddressSize::U8 | AddressSize::U16 | AddressSize::U32) => false,
+ Some(AddressSize::U64) => true,
+ _ => sess.dcx().fatal(format!(
+ "raw-dylib is not supported for the architecture `{}`",
+ sess.target.arch
+ )),
+ };
+
+ let mut stub = write::Writer::new(endianness, is_64, &mut stub_buf);
+
+ let mut vers = Vec::new();
+ let mut vers_map = FxHashMap::default();
+ let mut syms = Vec::new();
+
+ for symbol in symbols {
+ let symbol_name = symbol.name.as_str();
+ if let Some((name, version_name)) = symbol_name.split_once('@') {
+ assert!(!version_name.contains('@'));
+ let dynstr = stub.add_dynamic_string(name.as_bytes());
+ let ver = if let Some(&ver_id) = vers_map.get(version_name) {
+ ver_id
+ } else {
+ let id = vers.len();
+ vers_map.insert(version_name, id);
+ let dynstr = stub.add_dynamic_string(version_name.as_bytes());
+ vers.push((version_name, dynstr));
+ id
+ };
+ syms.push((name, dynstr, Some(ver)));
+ } else {
+ let dynstr = stub.add_dynamic_string(symbol_name.as_bytes());
+ syms.push((symbol_name, dynstr, None));
+ }
+ }
+
+ let soname = stub.add_dynamic_string(soname.as_bytes());
+
+ // These initial reservations don't reserve any bytes in the binary yet,
+ // they just allocate in the internal data structures.
+
+ // First, we create the dynamic symbol table. It starts with a null symbol
+ // and then all the symbols and their dynamic strings.
+ stub.reserve_null_dynamic_symbol_index();
+
+ for _ in syms.iter() {
+ stub.reserve_dynamic_symbol_index();
+ }
+
+ // Reserve the sections.
+ // We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to.
+ stub.reserve_shstrtab_section_index();
+ let text_section_name = stub.add_section_name(".text".as_bytes());
+ let text_section = stub.reserve_section_index();
+ stub.reserve_dynsym_section_index();
+ stub.reserve_dynstr_section_index();
+ if !vers.is_empty() {
+ stub.reserve_gnu_versym_section_index();
+ stub.reserve_gnu_verdef_section_index();
+ }
+ stub.reserve_dynamic_section_index();
+
+ // These reservations now determine the actual layout order of the object file.
+ stub.reserve_file_header();
+ stub.reserve_shstrtab();
+ stub.reserve_section_headers();
+ stub.reserve_dynsym();
+ stub.reserve_dynstr();
+ if !vers.is_empty() {
+ stub.reserve_gnu_versym();
+ stub.reserve_gnu_verdef(1 + vers.len(), 1 + vers.len());
+ }
+ stub.reserve_dynamic(2); // DT_SONAME, DT_NULL
+
+ // First write the ELF header with the arch information.
let e_machine = match (arch, sub_arch) {
(Architecture::Aarch64, None) => elf::EM_AARCH64,
(Architecture::Aarch64_Ilp32, None) => elf::EM_AARCH64,
@@ -342,18 +382,19 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
sh_addralign: 1,
sh_entsize: 0,
});
- stub.write_dynstr_section_header(0);
stub.write_dynsym_section_header(0, 1);
+ stub.write_dynstr_section_header(0);
+ if !vers.is_empty() {
+ stub.write_gnu_versym_section_header(0);
+ stub.write_gnu_verdef_section_header(0);
+ }
stub.write_dynamic_section_header(0);
- // .dynstr
- stub.write_dynstr();
-
// .dynsym
stub.write_null_dynamic_symbol();
- for (_, name) in dynstrs {
+ for (_name, dynstr, _ver) in syms.iter().copied() {
stub.write_dynamic_symbol(&write::Sym {
- name: Some(name),
+ name: Some(dynstr),
st_info: (elf::STB_GLOBAL << 4) | elf::STT_NOTYPE,
st_other: elf::STV_DEFAULT,
section: Some(text_section),
@@ -363,10 +404,47 @@ fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]
});
}
+ // .dynstr
+ stub.write_dynstr();
+
+ // ld.bfd is unhappy if these sections exist without any symbols, so we only generate them when necessary.
+ if !vers.is_empty() {
+ // .gnu_version
+ stub.write_null_gnu_versym();
+ for (_name, _dynstr, ver) in syms.iter().copied() {
+ stub.write_gnu_versym(if let Some(ver) = ver {
+ assert!((2 + ver as u16) < elf::VERSYM_HIDDEN);
+ elf::VERSYM_HIDDEN | (2 + ver as u16)
+ } else {
+ 1
+ });
+ }
+
+ // .gnu_version_d
+ stub.write_align_gnu_verdef();
+ stub.write_gnu_verdef(&write::Verdef {
+ version: elf::VER_DEF_CURRENT,
+ flags: elf::VER_FLG_BASE,
+ index: 1,
+ aux_count: 1,
+ name: soname,
+ });
+ for (ver, (_name, dynstr)) in vers.into_iter().enumerate() {
+ stub.write_gnu_verdef(&write::Verdef {
+ version: elf::VER_DEF_CURRENT,
+ flags: 0,
+ index: 2 + ver as u16,
+ aux_count: 1,
+ name: dynstr,
+ });
+ }
+ }
+
// .dynamic
// the DT_SONAME will be used by the linker to populate DT_NEEDED
// which the loader uses to find the library.
// DT_NULL terminates the .dynamic table.
+ stub.write_align_dynamic();
stub.write_dynamic_string(elf::DT_SONAME, soname);
stub.write_dynamic(elf::DT_NULL, 0);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 610e2fd..a5759b7 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -288,7 +288,7 @@ fn cast_immediate(
// valid ranges. For example, `char`s are passed as just `i32`, with no
// way for LLVM to know that they're 0x10FFFF at most. Thus we assume
// the range of the input value too, not just the output range.
- assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
+ assume_scalar_range(bx, imm, from_scalar, from_backend_ty, None);
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
(Int(_, is_signed), Int(..)) => bx.intcast(imm, to_backend_ty, is_signed),
@@ -1064,7 +1064,7 @@ pub(super) fn transmute_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// That said, last time we tried removing this, it didn't actually help
// the rustc-perf results, so might as well keep doing it
// <https://github.com/rust-lang/rust/pull/135610#issuecomment-2599275182>
- assume_scalar_range(bx, imm, from_scalar, from_backend_ty);
+ assume_scalar_range(bx, imm, from_scalar, from_backend_ty, Some(&to_scalar));
imm = match (from_scalar.primitive(), to_scalar.primitive()) {
(Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty),
@@ -1092,22 +1092,42 @@ pub(super) fn transmute_scalar<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// since it's never passed to something with parameter metadata (especially
// after MIR inlining) so the only way to tell the backend about the
// constraint that the `transmute` introduced is to `assume` it.
- assume_scalar_range(bx, imm, to_scalar, to_backend_ty);
+ assume_scalar_range(bx, imm, to_scalar, to_backend_ty, Some(&from_scalar));
imm = bx.to_immediate_scalar(imm, to_scalar);
imm
}
+/// Emits an `assume` call that `imm`'s value is within the known range of `scalar`.
+///
+/// If `known` is `Some`, only emits the assume if it's more specific than
+/// whatever is already known from the range of *that* scalar.
fn assume_scalar_range<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
bx: &mut Bx,
imm: Bx::Value,
scalar: abi::Scalar,
backend_ty: Bx::Type,
+ known: Option<&abi::Scalar>,
) {
- if matches!(bx.cx().sess().opts.optimize, OptLevel::No) || scalar.is_always_valid(bx.cx()) {
+ if matches!(bx.cx().sess().opts.optimize, OptLevel::No) {
return;
}
+ match (scalar, known) {
+ (abi::Scalar::Union { .. }, _) => return,
+ (_, None) => {
+ if scalar.is_always_valid(bx.cx()) {
+ return;
+ }
+ }
+ (abi::Scalar::Initialized { valid_range, .. }, Some(known)) => {
+ let known_range = known.valid_range(bx.cx());
+ if valid_range.contains_range(known_range, scalar.size(bx.cx())) {
+ return;
+ }
+ }
+ }
+
match scalar.primitive() {
abi::Primitive::Int(..) => {
let range = scalar.valid_range(bx.cx());
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 03c026c..bb1de5b 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1642,20 +1642,40 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
if def.repr().int.is_none() {
let is_unit = |var: &ty::VariantDef| matches!(var.ctor_kind(), Some(CtorKind::Const));
- let has_disr = |var: &ty::VariantDef| matches!(var.discr, ty::VariantDiscr::Explicit(_));
+ let get_disr = |var: &ty::VariantDef| match var.discr {
+ ty::VariantDiscr::Explicit(disr) => Some(disr),
+ ty::VariantDiscr::Relative(_) => None,
+ };
- let has_non_units = def.variants().iter().any(|var| !is_unit(var));
- let disr_units = def.variants().iter().any(|var| is_unit(var) && has_disr(var));
- let disr_non_unit = def.variants().iter().any(|var| !is_unit(var) && has_disr(var));
+ let non_unit = def.variants().iter().find(|var| !is_unit(var));
+ let disr_unit =
+ def.variants().iter().filter(|var| is_unit(var)).find_map(|var| get_disr(var));
+ let disr_non_unit =
+ def.variants().iter().filter(|var| !is_unit(var)).find_map(|var| get_disr(var));
- if disr_non_unit || (disr_units && has_non_units) {
- struct_span_code_err!(
+ if disr_non_unit.is_some() || (disr_unit.is_some() && non_unit.is_some()) {
+ let mut err = struct_span_code_err!(
tcx.dcx(),
tcx.def_span(def_id),
E0732,
- "`#[repr(inttype)]` must be specified"
- )
- .emit();
+ "`#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants"
+ );
+ if let Some(disr_non_unit) = disr_non_unit {
+ err.span_label(
+ tcx.def_span(disr_non_unit),
+ "explicit discriminant on non-unit variant specified here",
+ );
+ } else {
+ err.span_label(
+ tcx.def_span(disr_unit.unwrap()),
+ "explicit discriminant specified here",
+ );
+ err.span_label(
+ tcx.def_span(non_unit.unwrap().def_id),
+ "non-unit discriminant declared here",
+ );
+ }
+ err.emit();
}
}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
index 9abae33..646ff3c 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs
@@ -447,17 +447,30 @@ fn maybe_suggest_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) -
fn maybe_suggest_assoc_ty_bound(&self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>) {
let mut parents = self.tcx().hir_parent_iter(self_ty.hir_id);
- if let Some((_, hir::Node::AssocItemConstraint(constraint))) = parents.next()
+ if let Some((c_hir_id, hir::Node::AssocItemConstraint(constraint))) = parents.next()
&& let Some(obj_ty) = constraint.ty()
+ && let Some((_, hir::Node::TraitRef(trait_ref))) = parents.next()
{
- if let Some((_, hir::Node::TraitRef(..))) = parents.next()
- && let Some((_, hir::Node::Ty(ty))) = parents.next()
+ if let Some((_, hir::Node::Ty(ty))) = parents.next()
&& let hir::TyKind::TraitObject(..) = ty.kind
{
// Assoc ty bounds aren't permitted inside trait object types.
return;
}
+ if trait_ref
+ .path
+ .segments
+ .iter()
+ .find_map(|seg| {
+ seg.args.filter(|args| args.constraints.iter().any(|c| c.hir_id == c_hir_id))
+ })
+ .is_none_or(|args| args.parenthesized != hir::GenericArgsParentheses::No)
+ {
+ // Only consider angle-bracketed args (where we have a `=` to replace with `:`).
+ return;
+ }
+
let lo = if constraint.gen_args.span_ext.is_dummy() {
constraint.ident.span
} else {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index dd6eb73..d18f4e0 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -1302,8 +1302,10 @@ pub(crate) fn suggest_clone_for_ref(
None => ".clone()".to_string(),
};
+ let span = expr.span.find_oldest_ancestor_in_same_ctxt().shrink_to_hi();
+
diag.span_suggestion_verbose(
- expr.span.shrink_to_hi(),
+ span,
"consider using clone here",
suggestion,
Applicability::MachineApplicable,
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index be77410..df38c3a 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -1047,7 +1047,7 @@ fn perform_2229_migration_analysis(
}
}
}
- lint.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
+ lint.note("for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>");
let diagnostic_msg = format!(
"add a dummy let to cause {migrated_variables_concat} to be fully captured"
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 1a1cfc9f..69fe7fe 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -593,7 +593,7 @@
lint_non_fmt_panic = panic message is not a string literal
.note = this usage of `{$name}!()` is deprecated; it will be a hard error in Rust 2021
- .more_info_note = for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ .more_info_note = for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
.supports_fmt_note = the `{$name}!()` macro supports formatting, so there's no need for the `format!()` macro here
.supports_fmt_suggestion = remove the `format!(..)` macro call
.display_suggestion = add a "{"{"}{"}"}" format string to `Display` the message
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 73e6883..bf128b5 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1654,7 +1654,7 @@ fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
"`...` range patterns are deprecated",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>",
};
}
@@ -1835,7 +1835,7 @@ fn check_pat_post(&mut self, _cx: &EarlyContext<'_>, pat: &ast::Pat) {
"detects edition keywords being used as an identifier",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>",
};
}
@@ -2870,7 +2870,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
if let hir::Expr {
kind:
hir::ExprKind::InlineAsm(hir::InlineAsm {
- asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm,
+ asm_macro: asm_macro @ (AsmMacro::Asm | AsmMacro::NakedAsm),
template_strs,
options,
..
@@ -2878,6 +2878,15 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
..
} = expr
{
+ // Non-generic naked functions are allowed to define arbitrary
+ // labels.
+ if *asm_macro == AsmMacro::NakedAsm {
+ let def_id = expr.hir_id.owner.def_id;
+ if !cx.tcx.generics_of(def_id).requires_monomorphization(cx.tcx) {
+ return;
+ }
+ }
+
// asm with `options(raw)` does not do replacement with `{` and `}`.
let raw = options.contains(InlineAsmOptions::RAW);
diff --git a/compiler/rustc_lint/src/if_let_rescope.rs b/compiler/rustc_lint/src/if_let_rescope.rs
index 263ea6f..ff67ed1 100644
--- a/compiler/rustc_lint/src/if_let_rescope.rs
+++ b/compiler/rustc_lint/src/if_let_rescope.rs
@@ -87,7 +87,7 @@
rewriting in `match` is an option to preserve the semantics up to Edition 2021",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>",
};
}
diff --git a/compiler/rustc_lint/src/impl_trait_overcaptures.rs b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
index c17281d..b9afb62 100644
--- a/compiler/rustc_lint/src/impl_trait_overcaptures.rs
+++ b/compiler/rustc_lint/src/impl_trait_overcaptures.rs
@@ -71,7 +71,7 @@
"`impl Trait` will capture more lifetimes than possibly intended in edition 2024",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>",
};
}
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index c681dee..ccfba71 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -356,7 +356,16 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
let store = unerased_lint_store(tcx.sess);
if store.late_module_passes.is_empty() {
- late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
+ // If all builtin lints can be skipped, there is no point in running `late_lint_mod_inner`
+ // at all. This happens often for dependencies built with `--cap-lints=allow`.
+ let dont_need_to_run = tcx.lints_that_dont_need_to_run(());
+ let can_skip_lints = builtin_lints
+ .get_lints()
+ .iter()
+ .all(|lint| dont_need_to_run.contains(&LintId::of(lint)));
+ if !can_skip_lints {
+ late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
+ }
} else {
let builtin_lints = Box::new(builtin_lints) as Box<dyn LateLintPass<'tcx>>;
let mut binding = store
diff --git a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs
index ce280fe..7de6fbd 100644
--- a/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs
+++ b/compiler/rustc_lint/src/macro_expr_fragment_specifier_2024_migration.rs
@@ -65,7 +65,7 @@
/// to ensure the macros implement the desired behavior.
///
/// [editions]: https://doc.rust-lang.org/edition-guide/
- /// [macro matcher fragment specifiers]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html
+ /// [macro matcher fragment specifiers]: https://doc.rust-lang.org/edition-guide/rust-2024/macro-fragment-specifiers.html
/// [`cargo fix`]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html
pub EDITION_2024_EXPR_FRAGMENT_SPECIFIER,
Allow,
@@ -73,7 +73,7 @@
To keep the existing behavior, use the `expr_2021` fragment specifier.",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
- reference: "Migration Guide <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html>",
+ reference: "Migration Guide <https://doc.rust-lang.org/edition-guide/rust-2024/macro-fragment-specifiers.html>",
};
}
diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs
index affea1b..191eb72 100644
--- a/compiler/rustc_lint/src/passes.rs
+++ b/compiler/rustc_lint/src/passes.rs
@@ -92,7 +92,7 @@ macro_rules! expand_combined_late_lint_pass_methods {
/// Combines multiple lints passes into a single lint pass, at compile time,
/// for maximum speed. Each `check_foo` method in `$methods` within this pass
/// simply calls `check_foo` once per `$pass`. Compare with
-/// `LateLintPassObjects`, which is similar, but combines lint passes at
+/// `RuntimeCombinedLateLintPass`, which is similar, but combines lint passes at
/// runtime.
#[macro_export]
macro_rules! declare_combined_late_lint_pass {
@@ -123,10 +123,10 @@ impl<'tcx> $crate::LateLintPass<'tcx> for $name {
#[allow(rustc::lint_pass_impl_without_macro)]
impl $crate::LintPass for $name {
fn name(&self) -> &'static str {
- panic!()
+ stringify!($name)
}
fn get_lints(&self) -> LintVec {
- panic!()
+ $name::get_lints()
}
}
)
diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs
index 00fa049..d296ae4 100644
--- a/compiler/rustc_lint/src/shadowed_into_iter.rs
+++ b/compiler/rustc_lint/src/shadowed_into_iter.rs
@@ -32,7 +32,7 @@
"detects calling `into_iter` on arrays in Rust 2015 and 2018",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>",
};
}
@@ -61,7 +61,7 @@
"detects calling `into_iter` on boxed slices in Rust 2015, 2018, and 2021",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>"
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>"
};
}
diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs
index 4dda3c7..16e1fb0 100644
--- a/compiler/rustc_lint/src/static_mut_refs.rs
+++ b/compiler/rustc_lint/src/static_mut_refs.rs
@@ -54,7 +54,7 @@
"creating a shared reference to mutable static",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>",
explain_reason: false,
};
@edition Edition2024 => Deny;
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index a08d68e..b1edb5c 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -1814,7 +1814,7 @@
"suggest using `dyn Trait` for trait objects",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>",
};
}
@@ -2472,7 +2472,7 @@
"unsafe operations in unsafe functions without an explicit unsafe block are deprecated",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>",
explain_reason: false
};
@edition Edition2024 => Warn;
@@ -3445,7 +3445,7 @@
"detects usage of old versions of or-patterns",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html>",
};
}
@@ -3494,7 +3494,7 @@
prelude in future editions",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>",
};
}
@@ -3534,7 +3534,7 @@
prelude in future editions",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html>",
};
}
@@ -3571,7 +3571,7 @@
"identifiers that will be parsed as a prefix in Rust 2021",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html>",
};
crate_level_only
}
@@ -4100,7 +4100,7 @@
"never type fallback affecting unsafe function calls",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>",
report_in_deps: true,
};
@edition Edition2024 => Deny;
@@ -4155,7 +4155,7 @@
"never type fallback affecting unsafe function calls",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionAndFutureReleaseError(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>",
report_in_deps: true,
};
report_in_external_macro
@@ -4740,7 +4740,7 @@
"detects unsafe functions being used as safe functions",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/newly-unsafe-functions.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/newly-unsafe-functions.html>",
};
}
@@ -4776,7 +4776,7 @@
"detects missing unsafe keyword on extern declarations",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-extern.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-extern.html>",
};
}
@@ -4817,7 +4817,7 @@
"detects unsafe attributes outside of unsafe",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>",
};
}
@@ -5014,7 +5014,7 @@
"Detect and warn on significant change in drop order in tail expression location",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>",
};
}
@@ -5053,7 +5053,7 @@
"will be parsed as a guarded string in Rust 2024",
@future_incompatible = FutureIncompatibleInfo {
reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
- reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>",
+ reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>",
};
crate_level_only
}
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index 3bef5ca..4d3e879 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -330,3 +330,6 @@
metadata_whole_archive_needs_static =
linking modifier `whole-archive` is only compatible with `static` linking kind
+
+metadata_raw_dylib_malformed =
+ link name must be well-formed if link kind is `raw-dylib`
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 4a3b431..0332dba 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -815,3 +815,10 @@ pub struct AsyncDropTypesInDependency {
pub extern_crate: Symbol,
pub local_crate: Symbol,
}
+
+#[derive(Diagnostic)]
+#[diag(metadata_raw_dylib_malformed)]
+pub struct RawDylibMalformed {
+ #[primary_span]
+ pub span: Span,
+}
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 4d276f8..ed0f084 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -700,8 +700,21 @@ fn build_dll_import(
.link_ordinal
.map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord)));
+ let name = codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item));
+
+ if self.tcx.sess.target.binary_format == BinaryFormat::Elf {
+ let name = name.as_str();
+ if name.contains('\0') {
+ self.tcx.dcx().emit_err(errors::RawDylibMalformed { span });
+ } else if let Some((left, right)) = name.split_once('@')
+ && (left.is_empty() || right.is_empty() || right.contains('@'))
+ {
+ self.tcx.dcx().emit_err(errors::RawDylibMalformed { span });
+ }
+ }
+
DllImport {
- name: codegen_fn_attrs.link_name.unwrap_or_else(|| self.tcx.item_name(item)),
+ name,
import_name_type,
calling_convention,
span,
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 2d7ddd1..105736b 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -143,10 +143,8 @@ pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
};
// Similarly, the executable entrypoint must be instantiated exactly once.
- if let Some((entry_def_id, _)) = tcx.entry_fn(()) {
- if instance.def_id() == entry_def_id {
- return InstantiationMode::GloballyShared { may_conflict: false };
- }
+ if tcx.is_entrypoint(instance.def_id()) {
+ return InstantiationMode::GloballyShared { may_conflict: false };
}
// If the function is #[naked] or contains any other attribute that requires exactly-once
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 638dc2c..b0d579a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2152,9 +2152,6 @@
desc { |tcx| "collecting child items of module `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
- query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option<CrateNum> {
- desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) }
- }
/// Gets the number of definitions in a foreign crate.
///
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index aa2494a..66d1335 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -3377,6 +3377,11 @@ pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] {
self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
}
+ /// Return the crate imported by given use item.
+ pub fn extern_mod_stmt_cnum(self, def_id: LocalDefId) -> Option<CrateNum> {
+ self.resolutions(()).extern_crate_map.get(&def_id).copied()
+ }
+
pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Arc<ast::Crate>)> {
self.resolver_for_lowering_raw(()).0
}
@@ -3414,6 +3419,20 @@ pub fn needs_coroutine_by_move_body_def_id(self, def_id: DefId) -> bool {
pub fn do_not_recommend_impl(self, def_id: DefId) -> bool {
self.get_diagnostic_attr(def_id, sym::do_not_recommend).is_some()
}
+
+ /// Whether this def is one of the special bin crate entrypoint functions that must have a
+ /// monomorphization and also not be internalized in the bin crate.
+ pub fn is_entrypoint(self, def_id: DefId) -> bool {
+ if self.is_lang_item(def_id, LangItem::Start) {
+ return true;
+ }
+ if let Some((entry_def_id, _)) = self.entry_fn(())
+ && entry_def_id == def_id
+ {
+ return true;
+ }
+ false
+ }
}
/// Parameter attributes that can only be determined by examining the body of a function instead
@@ -3432,8 +3451,6 @@ pub struct DeducedParamAttrs {
}
pub fn provide(providers: &mut Providers) {
- providers.extern_mod_stmt_cnum =
- |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned();
providers.is_panic_runtime =
|tcx, LocalCrate| contains_name(tcx.hir_krate_attrs(), sym::panic_runtime);
providers.is_compiler_builtins =
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index e339520..abfe8eb 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -86,10 +86,16 @@
mir_build_const_continue_bad_const = could not determine the target branch for this `#[const_continue]`
.label = this value is too generic
- .note = the value must be a literal or a monomorphic const
mir_build_const_continue_missing_value = a `#[const_continue]` must break to a label with a value
+mir_build_const_continue_not_const = could not determine the target branch for this `#[const_continue]`
+ .help = try extracting the expression into a `const` item
+
+mir_build_const_continue_not_const_const_block = `const` blocks may use generics, and are not evaluated early enough
+mir_build_const_continue_not_const_const_other = this value must be a literal or a monomorphic const
+mir_build_const_continue_not_const_constant_parameter = constant parameters may use generics, and are not evaluated early enough
+
mir_build_const_continue_unknown_jump_target = the target of this `#[const_continue]` is not statically known
.label = this value must be a literal or a monomorphic const
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
index daf8fa5..a4ef6e9 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_rvalue.rs
@@ -1,6 +1,6 @@
//! See docs in `build/expr/mod.rs`.
-use rustc_abi::{BackendRepr, FieldIdx, Primitive};
+use rustc_abi::FieldIdx;
use rustc_hir::lang_items::LangItem;
use rustc_index::{Idx, IndexVec};
use rustc_middle::bug;
@@ -9,7 +9,6 @@
use rustc_middle::mir::*;
use rustc_middle::thir::*;
use rustc_middle::ty::cast::{CastTy, mir_cast_kind};
-use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, Ty, UpvarArgs};
use rustc_span::source_map::Spanned;
@@ -200,8 +199,6 @@ pub(crate) fn as_rvalue(
{
let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx);
let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not));
- let layout =
- this.tcx.layout_of(this.typing_env().as_query_input(source_expr.ty));
let discr = this.temp(discr_ty, source_expr.span);
this.cfg.push_assign(
block,
@@ -209,80 +206,7 @@ pub(crate) fn as_rvalue(
discr,
Rvalue::Discriminant(temp.into()),
);
- let (op, ty) = (Operand::Move(discr), discr_ty);
-
- if let BackendRepr::Scalar(scalar) = layout.unwrap().backend_repr
- && !scalar.is_always_valid(&this.tcx)
- && let Primitive::Int(int_width, _signed) = scalar.primitive()
- {
- let unsigned_ty = int_width.to_ty(this.tcx, false);
- let unsigned_place = this.temp(unsigned_ty, expr_span);
- this.cfg.push_assign(
- block,
- source_info,
- unsigned_place,
- Rvalue::Cast(CastKind::IntToInt, Operand::Copy(discr), unsigned_ty),
- );
-
- let bool_ty = this.tcx.types.bool;
- let range = scalar.valid_range(&this.tcx);
- let merge_op =
- if range.start <= range.end { BinOp::BitAnd } else { BinOp::BitOr };
-
- let mut comparer = |range: u128, bin_op: BinOp| -> Place<'tcx> {
- // We can use `ty::TypingEnv::fully_monomorphized()` here
- // as we only need it to compute the layout of a primitive.
- let range_val = Const::from_bits(
- this.tcx,
- range,
- ty::TypingEnv::fully_monomorphized(),
- unsigned_ty,
- );
- let lit_op = this.literal_operand(expr.span, range_val);
- let is_bin_op = this.temp(bool_ty, expr_span);
- this.cfg.push_assign(
- block,
- source_info,
- is_bin_op,
- Rvalue::BinaryOp(
- bin_op,
- Box::new((Operand::Copy(unsigned_place), lit_op)),
- ),
- );
- is_bin_op
- };
- let assert_place = if range.start == 0 {
- comparer(range.end, BinOp::Le)
- } else {
- let start_place = comparer(range.start, BinOp::Ge);
- let end_place = comparer(range.end, BinOp::Le);
- let merge_place = this.temp(bool_ty, expr_span);
- this.cfg.push_assign(
- block,
- source_info,
- merge_place,
- Rvalue::BinaryOp(
- merge_op,
- Box::new((
- Operand::Move(start_place),
- Operand::Move(end_place),
- )),
- ),
- );
- merge_place
- };
- this.cfg.push(
- block,
- Statement::new(
- source_info,
- StatementKind::Intrinsic(Box::new(NonDivergingIntrinsic::Assume(
- Operand::Move(assert_place),
- ))),
- ),
- );
- }
-
- (op, ty)
+ (Operand::Move(discr), discr_ty)
} else {
let ty = source_expr.ty;
let source = unpack!(
diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs
index 12a56d7..1240b34 100644
--- a/compiler/rustc_mir_build/src/builder/scope.rs
+++ b/compiler/rustc_mir_build/src/builder/scope.rs
@@ -100,7 +100,9 @@
use super::matches::BuiltMatchTree;
use crate::builder::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG};
-use crate::errors::{ConstContinueBadConst, ConstContinueUnknownJumpTarget};
+use crate::errors::{
+ ConstContinueBadConst, ConstContinueNotMonomorphicConst, ConstContinueUnknownJumpTarget,
+};
#[derive(Debug)]
pub(crate) struct Scopes<'tcx> {
@@ -867,7 +869,8 @@ pub(crate) fn break_const_continuable_scope(
span_bug!(span, "break value must be a scope")
};
- let constant = match &self.thir[value].kind {
+ let expr = &self.thir[value];
+ let constant = match &expr.kind {
ExprKind::Adt(box AdtExpr { variant_index, fields, base, .. }) => {
assert!(matches!(base, AdtExprBase::None));
assert!(fields.is_empty());
@@ -887,7 +890,27 @@ pub(crate) fn break_const_continuable_scope(
),
}
}
- _ => self.as_constant(&self.thir[value]),
+
+ ExprKind::Literal { .. }
+ | ExprKind::NonHirLiteral { .. }
+ | ExprKind::ZstLiteral { .. }
+ | ExprKind::NamedConst { .. } => self.as_constant(&self.thir[value]),
+
+ other => {
+ use crate::errors::ConstContinueNotMonomorphicConstReason as Reason;
+
+ let span = expr.span;
+ let reason = match other {
+ ExprKind::ConstParam { .. } => Reason::ConstantParameter { span },
+ ExprKind::ConstBlock { .. } => Reason::ConstBlock { span },
+ _ => Reason::Other { span },
+ };
+
+ self.tcx
+ .dcx()
+ .emit_err(ConstContinueNotMonomorphicConst { span: expr.span, reason });
+ return block.unit();
+ }
};
let break_index = self
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 16b49bf..f1fbd5c 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -1214,6 +1214,38 @@ pub(crate) struct LoopMatchArmWithGuard {
}
#[derive(Diagnostic)]
+#[diag(mir_build_const_continue_not_const)]
+#[help]
+pub(crate) struct ConstContinueNotMonomorphicConst {
+ #[primary_span]
+ pub span: Span,
+
+ #[subdiagnostic]
+ pub reason: ConstContinueNotMonomorphicConstReason,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum ConstContinueNotMonomorphicConstReason {
+ #[label(mir_build_const_continue_not_const_constant_parameter)]
+ ConstantParameter {
+ #[primary_span]
+ span: Span,
+ },
+
+ #[label(mir_build_const_continue_not_const_const_block)]
+ ConstBlock {
+ #[primary_span]
+ span: Span,
+ },
+
+ #[label(mir_build_const_continue_not_const_const_other)]
+ Other {
+ #[primary_span]
+ span: Span,
+ },
+}
+
+#[derive(Diagnostic)]
#[diag(mir_build_const_continue_bad_const)]
pub(crate) struct ConstContinueBadConst {
#[primary_span]
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index d435e4e..1bfd83d 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1575,6 +1575,15 @@ fn push_extra_entry_roots(&mut self) {
return;
};
+ let main_instance = Instance::mono(self.tcx, main_def_id);
+ if self.tcx.should_codegen_locally(main_instance) {
+ self.output.push(create_fn_mono_item(
+ self.tcx,
+ main_instance,
+ self.tcx.def_span(main_def_id),
+ ));
+ }
+
let Some(start_def_id) = self.tcx.lang_items().start_fn() else {
self.tcx.dcx().emit_fatal(errors::StartNotFound);
};
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 6985151..ca8228d 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -223,11 +223,7 @@ fn place_mono_items<'tcx, I>(cx: &PartitioningCx<'_, 'tcx>, mono_items: I) -> Pl
// So even if its mode is LocalCopy, we need to treat it like a root.
match mono_item.instantiation_mode(cx.tcx) {
InstantiationMode::GloballyShared { .. } => {}
- InstantiationMode::LocalCopy => {
- if !cx.tcx.is_lang_item(mono_item.def_id(), LangItem::Start) {
- continue;
- }
- }
+ InstantiationMode::LocalCopy => continue,
}
let characteristic_def_id = characteristic_def_id_of_mono_item(cx.tcx, mono_item);
@@ -821,10 +817,9 @@ fn mono_item_visibility<'tcx>(
| InstanceKind::FnPtrAddrShim(..) => return Visibility::Hidden,
};
- // The `start_fn` lang item is actually a monomorphized instance of a
- // function in the standard library, used for the `main` function. We don't
- // want to export it so we tag it with `Hidden` visibility but this symbol
- // is only referenced from the actual `main` symbol which we unfortunately
+ // Both the `start_fn` lang item and `main` itself should not be exported,
+ // so we give them with `Hidden` visibility but these symbols are
+ // only referenced from the actual `main` symbol which we unfortunately
// don't know anything about during partitioning/collection. As a result we
// forcibly keep this symbol out of the `internalization_candidates` set.
//
@@ -834,7 +829,7 @@ fn mono_item_visibility<'tcx>(
// from the `main` symbol we'll generate later.
//
// This may be fixable with a new `InstanceKind` perhaps? Unsure!
- if tcx.is_lang_item(def_id, LangItem::Start) {
+ if tcx.is_entrypoint(def_id) {
*can_be_internalized = false;
return Visibility::Hidden;
}
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index ed7fb77..73a341c 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -285,6 +285,9 @@ pub fn check_builtin_meta_item(
| sym::rustc_do_not_implement_via_object
| sym::rustc_coinductive
| sym::const_trait
+ | sym::stable
+ | sym::unstable
+ | sym::rustc_allowed_through_unstable_modules
| sym::rustc_specialization_trait
| sym::rustc_unsafe_specialization_marker
| sym::rustc_allow_incoherent_impl
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 04c1933..4b524bb 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1258,7 +1258,7 @@ fn check_doc_masked(
return;
}
- if self.tcx.extern_mod_stmt_cnum(hir_id.owner).is_none() {
+ if self.tcx.extern_mod_stmt_cnum(hir_id.owner.def_id).is_none() {
self.tcx.emit_node_span_lint(
INVALID_DOC_ATTRIBUTES,
hir_id,
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 9dd80bc..6fd2b7f 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -26,7 +26,7 @@
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId};
use rustc_hir::intravisit::{self, InferKind, Visitor};
-use rustc_hir::{AmbigArg, ForeignItemKind, ItemId, ItemKind, PatKind};
+use rustc_hir::{AmbigArg, ForeignItemId, ItemId, PatKind};
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
use rustc_middle::query::Providers;
use rustc_middle::ty::print::PrintTraitRefExt as _;
@@ -599,18 +599,13 @@ fn update_macro_reachable_def(
DefKind::Struct | DefKind::Union => {
// While structs and unions have type privacy, their fields do not.
- let item = self.tcx.hir_expect_item(def_id);
- if let hir::ItemKind::Struct(_, _, ref struct_def)
- | hir::ItemKind::Union(_, _, ref struct_def) = item.kind
- {
- for field in struct_def.fields() {
- let field_vis = self.tcx.local_visibility(field.def_id);
- if field_vis.is_accessible_from(module, self.tcx) {
- self.reach(field.def_id, macro_ev).ty();
- }
+ let struct_def = self.tcx.adt_def(def_id);
+ for field in struct_def.non_enum_variant().fields.iter() {
+ let def_id = field.did.expect_local();
+ let field_vis = self.tcx.local_visibility(def_id);
+ if field_vis.is_accessible_from(module, self.tcx) {
+ self.reach(def_id, macro_ev).ty();
}
- } else {
- bug!("item {:?} with DefKind {:?}", item, def_kind);
}
}
@@ -1644,66 +1639,29 @@ fn check_item(&mut self, id: ItemId) {
self.check(def_id, item_visibility, effective_vis).generics().predicates();
}
DefKind::Enum => {
- let item = tcx.hir_item(id);
- if let hir::ItemKind::Enum(_, _, ref def) = item.kind {
- self.check_unnameable(item.owner_id.def_id, effective_vis);
+ self.check_unnameable(def_id, effective_vis);
+ self.check(def_id, item_visibility, effective_vis).generics().predicates();
- self.check(item.owner_id.def_id, item_visibility, effective_vis)
- .generics()
- .predicates();
-
- for variant in def.variants {
- for field in variant.data.fields() {
- self.check(field.def_id, item_visibility, effective_vis).ty();
- }
- }
- }
- }
- // Subitems of foreign modules have their own publicity.
- DefKind::ForeignMod => {
- let item = tcx.hir_item(id);
- if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
- for &foreign_item in items {
- let foreign_item = tcx.hir_foreign_item(foreign_item);
-
- let ev = self.get(foreign_item.owner_id.def_id);
- let vis = tcx.local_visibility(foreign_item.owner_id.def_id);
-
- if let ForeignItemKind::Type = foreign_item.kind {
- self.check_unnameable(foreign_item.owner_id.def_id, ev);
- }
-
- self.check(foreign_item.owner_id.def_id, vis, ev)
- .generics()
- .predicates()
- .ty();
- }
+ let adt = tcx.adt_def(id.owner_id);
+ for field in adt.all_fields() {
+ self.check(field.did.expect_local(), item_visibility, effective_vis).ty();
}
}
// Subitems of structs and unions have their own publicity.
DefKind::Struct | DefKind::Union => {
- let item = tcx.hir_item(id);
- if let hir::ItemKind::Struct(_, _, ref struct_def)
- | hir::ItemKind::Union(_, _, ref struct_def) = item.kind
- {
- self.check_unnameable(item.owner_id.def_id, effective_vis);
- self.check(item.owner_id.def_id, item_visibility, effective_vis)
- .generics()
- .predicates();
+ self.check_unnameable(def_id, effective_vis);
+ self.check(def_id, item_visibility, effective_vis).generics().predicates();
- for field in struct_def.fields() {
- let field_visibility = tcx.local_visibility(field.def_id);
- let field_ev = self.get(field.def_id);
+ let adt = tcx.adt_def(id.owner_id);
+ for field in adt.all_fields() {
+ let visibility = min(item_visibility, field.vis.expect_local(), tcx);
+ let field_ev = self.get(field.did.expect_local());
- self.check(
- field.def_id,
- min(item_visibility, field_visibility, tcx),
- field_ev,
- )
- .ty();
- }
+ self.check(field.did.expect_local(), visibility, field_ev).ty();
}
}
+ // Subitems of foreign modules have their own publicity.
+ DefKind::ForeignMod => {}
// An inherent impl is public when its type is public
// Subitems of inherent impls have their own publicity.
// A trait impl is public when both its type and its trait are public
@@ -1763,6 +1721,19 @@ fn check_item(&mut self, id: ItemId) {
_ => {}
}
}
+
+ fn check_foreign_item(&mut self, id: ForeignItemId) {
+ let tcx = self.tcx;
+ let def_id = id.owner_id.def_id;
+ let item_visibility = tcx.local_visibility(def_id);
+ let effective_vis = self.get(def_id);
+
+ if let DefKind::ForeignTy = self.tcx.def_kind(def_id) {
+ self.check_unnameable(def_id, effective_vis);
+ }
+
+ self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
+ }
}
pub fn provide(providers: &mut Providers) {
@@ -1791,20 +1762,13 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
if let Some(body_id) = tcx.hir_maybe_body_owned_by(def_id) {
visitor.visit_nested_body(body_id.id());
}
- }
- for id in module.free_items() {
- if let ItemKind::Impl(i) = tcx.hir_item(id).kind {
- if let Some(item) = i.of_trait {
- let trait_ref = tcx.impl_trait_ref(id.owner_id.def_id).unwrap();
- let trait_ref = trait_ref.instantiate_identity();
- visitor.span = item.path.span;
- let _ = visitor.visit_def_id(
- trait_ref.def_id,
- "trait",
- &trait_ref.print_only_trait_path(),
- );
- }
+ if let DefKind::Impl { of_trait: true } = tcx.def_kind(def_id) {
+ let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
+ let trait_ref = trait_ref.instantiate_identity();
+ visitor.span = tcx.hir_expect_item(def_id).expect_impl().of_trait.unwrap().path.span;
+ let _ =
+ visitor.visit_def_id(trait_ref.def_id, "trait", &trait_ref.print_only_trait_path());
}
}
}
@@ -1895,7 +1859,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
// Check for private types in public interfaces.
let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
- for id in tcx.hir_free_items() {
+ let crate_items = tcx.hir_crate_items(());
+ for id in crate_items.free_items() {
checker.check_item(id);
}
+ for id in crate_items.foreign_items() {
+ checker.check_foreign_item(id);
+ }
}
diff --git a/compiler/rustc_public/src/mir/body.rs b/compiler/rustc_public/src/mir/body.rs
index 3320b98..3d59528 100644
--- a/compiler/rustc_public/src/mir/body.rs
+++ b/compiler/rustc_public/src/mir/body.rs
@@ -654,9 +654,7 @@ pub fn ty(&self, locals: &[LocalDecl]) -> Result<Ty, Error> {
)),
AggregateKind::Adt(def, _, ref args, _, _) => Ok(def.ty_with_args(args)),
AggregateKind::Closure(def, ref args) => Ok(Ty::new_closure(def, args.clone())),
- AggregateKind::Coroutine(def, ref args, mov) => {
- Ok(Ty::new_coroutine(def, args.clone(), mov))
- }
+ AggregateKind::Coroutine(def, ref args) => Ok(Ty::new_coroutine(def, args.clone())),
AggregateKind::CoroutineClosure(def, ref args) => {
Ok(Ty::new_coroutine_closure(def, args.clone()))
}
@@ -674,8 +672,7 @@ pub enum AggregateKind {
Tuple,
Adt(AdtDef, VariantIdx, GenericArgs, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
Closure(ClosureDef, GenericArgs),
- // FIXME(rustc_public): Movability here is redundant
- Coroutine(CoroutineDef, GenericArgs, Movability),
+ Coroutine(CoroutineDef, GenericArgs),
CoroutineClosure(CoroutineClosureDef, GenericArgs),
RawPtr(Ty, Mutability),
}
diff --git a/compiler/rustc_public/src/mir/pretty.rs b/compiler/rustc_public/src/mir/pretty.rs
index a433df2..3183c02 100644
--- a/compiler/rustc_public/src/mir/pretty.rs
+++ b/compiler/rustc_public/src/mir/pretty.rs
@@ -428,7 +428,7 @@ fn pretty_aggregate<W: Write>(
write!(writer, "{{closure@{}}}(", def.span().diagnostic())?;
")"
}
- AggregateKind::Coroutine(def, _, _) => {
+ AggregateKind::Coroutine(def, _) => {
write!(writer, "{{coroutine@{}}}(", def.span().diagnostic())?;
")"
}
diff --git a/compiler/rustc_public/src/ty.rs b/compiler/rustc_public/src/ty.rs
index bc67a2f..de4b21b 100644
--- a/compiler/rustc_public/src/ty.rs
+++ b/compiler/rustc_public/src/ty.rs
@@ -60,8 +60,8 @@ pub fn new_closure(def: ClosureDef, args: GenericArgs) -> Ty {
}
/// Create a new coroutine type.
- pub fn new_coroutine(def: CoroutineDef, args: GenericArgs, mov: Movability) -> Ty {
- Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
+ pub fn new_coroutine(def: CoroutineDef, args: GenericArgs) -> Ty {
+ Ty::from_rigid_kind(RigidTy::Coroutine(def, args))
}
/// Create a new closure type.
@@ -560,8 +560,7 @@ pub enum RigidTy {
FnDef(FnDef, GenericArgs),
FnPtr(PolyFnSig),
Closure(ClosureDef, GenericArgs),
- // FIXME(rustc_public): Movability here is redundant
- Coroutine(CoroutineDef, GenericArgs, Movability),
+ Coroutine(CoroutineDef, GenericArgs),
CoroutineClosure(CoroutineClosureDef, GenericArgs),
Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
Never,
diff --git a/compiler/rustc_public/src/unstable/convert/internal.rs b/compiler/rustc_public/src/unstable/convert/internal.rs
index b2d38e49..66f767a 100644
--- a/compiler/rustc_public/src/unstable/convert/internal.rs
+++ b/compiler/rustc_public/src/unstable/convert/internal.rs
@@ -177,7 +177,7 @@ fn internal<'tcx>(
RigidTy::Closure(def, args) => {
rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx))
}
- RigidTy::Coroutine(def, args, _mov) => {
+ RigidTy::Coroutine(def, args) => {
rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx))
}
RigidTy::CoroutineClosure(def, args) => rustc_ty::TyKind::CoroutineClosure(
diff --git a/compiler/rustc_public/src/unstable/convert/stable/mir.rs b/compiler/rustc_public/src/unstable/convert/stable/mir.rs
index 8dee579..be8ee80 100644
--- a/compiler/rustc_public/src/unstable/convert/stable/mir.rs
+++ b/compiler/rustc_public/src/unstable/convert/stable/mir.rs
@@ -653,7 +653,6 @@ fn stable<'cx>(
crate::mir::AggregateKind::Coroutine(
tables.coroutine_def(*def_id),
generic_arg.stable(tables, cx),
- cx.coroutine_movability(*def_id).stable(tables, cx),
)
}
mir::AggregateKind::CoroutineClosure(def_id, generic_args) => {
diff --git a/compiler/rustc_public/src/unstable/convert/stable/ty.rs b/compiler/rustc_public/src/unstable/convert/stable/ty.rs
index d679615..5a66107 100644
--- a/compiler/rustc_public/src/unstable/convert/stable/ty.rs
+++ b/compiler/rustc_public/src/unstable/convert/stable/ty.rs
@@ -457,7 +457,6 @@ fn stable<'cx>(
ty::Coroutine(def_id, generic_args) => TyKind::RigidTy(RigidTy::Coroutine(
tables.coroutine_def(*def_id),
generic_args.stable(tables, cx),
- cx.coroutine_movability(*def_id).stable(tables, cx),
)),
ty::Never => TyKind::RigidTy(RigidTy::Never),
ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple(
diff --git a/compiler/rustc_public/src/visitor.rs b/compiler/rustc_public/src/visitor.rs
index 45e2a81..87f1cc6 100644
--- a/compiler/rustc_public/src/visitor.rs
+++ b/compiler/rustc_public/src/visitor.rs
@@ -166,7 +166,7 @@ fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
}
RigidTy::Adt(_, args)
| RigidTy::Closure(_, args)
- | RigidTy::Coroutine(_, args, _)
+ | RigidTy::Coroutine(_, args)
| RigidTy::CoroutineWitness(_, args)
| RigidTy::CoroutineClosure(_, args)
| RigidTy::FnDef(_, args) => args.visit(visitor),
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index d72fbc1..75eed1e 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1076,11 +1076,6 @@ fn early_lookup_typo_candidate(
}
}
}
- Scope::CrateRoot => {
- let root_ident = Ident::new(kw::PathRoot, ident.span);
- let root_module = this.resolve_crate_root(root_ident);
- this.add_module_candidates(root_module, &mut suggestions, filter_fn, None);
- }
Scope::Module(module, _) => {
this.add_module_candidates(module, &mut suggestions, filter_fn, None);
}
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 3494139..71cc68a 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -93,20 +93,21 @@ pub(crate) fn visit_scopes<T>(
// 6. Language prelude: builtin attributes (closed, controlled).
let rust_2015 = ctxt.edition().is_rust_2015();
- let (ns, macro_kind, is_absolute_path) = match scope_set {
- ScopeSet::All(ns) => (ns, None, false),
- ScopeSet::AbsolutePath(ns) => (ns, None, true),
- ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
- ScopeSet::Late(ns, ..) => (ns, None, false),
+ let (ns, macro_kind) = match scope_set {
+ ScopeSet::All(ns)
+ | ScopeSet::ModuleAndExternPrelude(ns, _)
+ | ScopeSet::Late(ns, ..) => (ns, None),
+ ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
};
let module = match scope_set {
// Start with the specified module.
- ScopeSet::Late(_, module, _) => module,
+ ScopeSet::Late(_, module, _) | ScopeSet::ModuleAndExternPrelude(_, module) => module,
// Jump out of trait or enum modules, they do not act as scopes.
_ => parent_scope.module.nearest_item_scope(),
};
+ let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..));
let mut scope = match ns {
- _ if is_absolute_path => Scope::CrateRoot,
+ _ if module_and_extern_prelude => Scope::Module(module, None),
TypeNS | ValueNS => Scope::Module(module, None),
MacroNS => Scope::DeriveHelpers(parent_scope.expansion),
};
@@ -134,11 +135,10 @@ pub(crate) fn visit_scopes<T>(
}
true
}
- Scope::CrateRoot => true,
Scope::Module(..) => true,
Scope::MacroUsePrelude => use_prelude || rust_2015,
Scope::BuiltinAttrs => true,
- Scope::ExternPrelude => use_prelude || is_absolute_path,
+ Scope::ExternPrelude => use_prelude || module_and_extern_prelude,
Scope::ToolPrelude => use_prelude,
Scope::StdLibPrelude => use_prelude || ns == MacroNS,
Scope::BuiltinTypes => true,
@@ -174,7 +174,7 @@ pub(crate) fn visit_scopes<T>(
}
MacroRulesScope::Empty => Scope::Module(module, None),
},
- Scope::CrateRoot => match ns {
+ Scope::Module(..) if module_and_extern_prelude => match ns {
TypeNS => {
ctxt.adjust(ExpnId::root());
Scope::ExternPrelude
@@ -203,7 +203,7 @@ pub(crate) fn visit_scopes<T>(
}
Scope::MacroUsePrelude => Scope::StdLibPrelude,
Scope::BuiltinAttrs => break, // nowhere else to search
- Scope::ExternPrelude if is_absolute_path => break,
+ Scope::ExternPrelude if module_and_extern_prelude => break,
Scope::ExternPrelude => Scope::ToolPrelude,
Scope::ToolPrelude => Scope::StdLibPrelude,
Scope::StdLibPrelude => match ns {
@@ -404,10 +404,10 @@ struct Flags: u8 {
}
let (ns, macro_kind) = match scope_set {
- ScopeSet::All(ns) => (ns, None),
- ScopeSet::AbsolutePath(ns) => (ns, None),
+ ScopeSet::All(ns)
+ | ScopeSet::ModuleAndExternPrelude(ns, _)
+ | ScopeSet::Late(ns, ..) => (ns, None),
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
- ScopeSet::Late(ns, ..) => (ns, None),
};
// This is *the* result, resolution from the scope closest to the resolved identifier.
@@ -487,31 +487,16 @@ struct Flags: u8 {
MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined),
_ => Err(Determinacy::Determined),
},
- Scope::CrateRoot => {
- let root_ident = Ident::new(kw::PathRoot, ident.span);
- let root_module = this.resolve_crate_root(root_ident);
- let binding = this.resolve_ident_in_module(
- ModuleOrUniformRoot::Module(root_module),
- ident,
- ns,
- parent_scope,
- finalize,
- ignore_binding,
- ignore_import,
- );
- match binding {
- Ok(binding) => Ok((binding, Flags::MODULE | Flags::MISC_SUGGEST_CRATE)),
- Err((Determinacy::Undetermined, Weak::No)) => {
- return Some(Err(Determinacy::determined(force)));
- }
- Err((Determinacy::Undetermined, Weak::Yes)) => {
- Err(Determinacy::Undetermined)
- }
- Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
- }
- }
Scope::Module(module, derive_fallback_lint_id) => {
- let adjusted_parent_scope = &ParentScope { module, ..*parent_scope };
+ let (adjusted_parent_scope, finalize) =
+ if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) {
+ (parent_scope, finalize)
+ } else {
+ (
+ &ParentScope { module, ..*parent_scope },
+ finalize.map(|f| Finalize { used: Used::Scope, ..f }),
+ )
+ };
let binding = this.resolve_ident_in_module_unadjusted(
ModuleOrUniformRoot::Module(module),
ident,
@@ -522,7 +507,7 @@ struct Flags: u8 {
} else {
Shadowing::Restricted
},
- finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }),
+ finalize,
ignore_binding,
ignore_import,
);
@@ -776,7 +761,7 @@ pub(crate) fn resolve_ident_in_module(
ModuleOrUniformRoot::ExternPrelude => {
ident.span.normalize_to_macros_2_0_and_adjust(ExpnId::root());
}
- ModuleOrUniformRoot::CrateRootAndExternPrelude | ModuleOrUniformRoot::CurrentScope => {
+ ModuleOrUniformRoot::ModuleAndExternPrelude(..) | ModuleOrUniformRoot::CurrentScope => {
// No adjustments
}
}
@@ -810,11 +795,11 @@ fn resolve_ident_in_module_unadjusted(
) -> Result<NameBinding<'ra>, (Determinacy, Weak)> {
let module = match module {
ModuleOrUniformRoot::Module(module) => module,
- ModuleOrUniformRoot::CrateRootAndExternPrelude => {
+ ModuleOrUniformRoot::ModuleAndExternPrelude(module) => {
assert_eq!(shadowing, Shadowing::Unrestricted);
let binding = self.early_resolve_ident_in_lexical_scope(
ident,
- ScopeSet::AbsolutePath(ns),
+ ScopeSet::ModuleAndExternPrelude(ns, module),
parent_scope,
finalize,
finalize.is_some(),
@@ -1531,7 +1516,8 @@ pub(crate) fn resolve_path_with_ribs(
&& self.tcx.sess.at_least_rust_2018()
{
// `::a::b` from 2015 macro on 2018 global edition
- module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude);
+ let crate_root = self.resolve_crate_root(ident);
+ module = Some(ModuleOrUniformRoot::ModuleAndExternPrelude(crate_root));
continue;
}
if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 783c500..986e703 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -181,10 +181,10 @@ pub(crate) struct ImportData<'ra> {
///
/// | `module_path` | `imported_module` | remark |
/// |-|-|-|
- /// |`use prefix::foo`| `ModuleOrUniformRoot::Module(prefix)` | - |
- /// |`use ::foo` | `ModuleOrUniformRoot::ExternPrelude` | 2018+ editions |
- /// |`use ::foo` | `ModuleOrUniformRoot::CrateRootAndExternPrelude` | a special case in 2015 edition |
- /// |`use foo` | `ModuleOrUniformRoot::CurrentScope` | - |
+ /// |`use prefix::foo`| `ModuleOrUniformRoot::Module(prefix)` | - |
+ /// |`use ::foo` | `ModuleOrUniformRoot::ExternPrelude` | 2018+ editions |
+ /// |`use ::foo` | `ModuleOrUniformRoot::ModuleAndExternPrelude` | a special case in 2015 edition |
+ /// |`use foo` | `ModuleOrUniformRoot::CurrentScope` | - |
pub imported_module: Cell<Option<ModuleOrUniformRoot<'ra>>>,
pub vis: Visibility,
}
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 08f1f61..27e14e0 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -119,7 +119,6 @@ enum Scope<'ra> {
DeriveHelpers(LocalExpnId),
DeriveHelpersCompat,
MacroRules(MacroRulesScopeRef<'ra>),
- CrateRoot,
// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK`
// lint if it should be reported.
Module(Module<'ra>, Option<NodeId>),
@@ -139,8 +138,8 @@ enum Scope<'ra> {
enum ScopeSet<'ra> {
/// All scopes with the given namespace.
All(Namespace),
- /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros).
- AbsolutePath(Namespace),
+ /// A module, then extern prelude (used for mixed 2015-2018 mode in macros).
+ ModuleAndExternPrelude(Namespace, Module<'ra>),
/// All scopes with macro namespace and the given macro kind restriction.
Macro(MacroKind),
/// All scopes with the given namespace, used for partially performing late resolution.
@@ -419,8 +418,10 @@ enum ModuleOrUniformRoot<'ra> {
/// Regular module.
Module(Module<'ra>),
- /// Virtual module that denotes resolution in crate root with fallback to extern prelude.
- CrateRootAndExternPrelude,
+ /// Virtual module that denotes resolution in a module with fallback to extern prelude.
+ /// Used for paths starting with `::` coming from 2015 edition macros
+ /// used in 2018+ edition crates.
+ ModuleAndExternPrelude(Module<'ra>),
/// Virtual module that denotes resolution in extern prelude.
/// Used for paths starting with `::` on 2018 edition.
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index 24e15de..6450f63 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -509,9 +509,8 @@ fn collect_link_data<'input, F: BrokenLinkCallback<'input>>(
display_text.map(String::into_boxed_str)
}
-/// Returns a tuple containing a span encompassing all the document fragments and a boolean that is
-/// `true` if any of the fragments are from a macro expansion.
-pub fn span_of_fragments_with_expansion(fragments: &[DocFragment]) -> Option<(Span, bool)> {
+/// Returns a span encompassing all the document fragments.
+pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
let (first_fragment, last_fragment) = match fragments {
[] => return None,
[first, .., last] => (first, last),
@@ -520,15 +519,7 @@ pub fn span_of_fragments_with_expansion(fragments: &[DocFragment]) -> Option<(Sp
if first_fragment.span == DUMMY_SP {
return None;
}
- Some((
- first_fragment.span.to(last_fragment.span),
- fragments.iter().any(|frag| frag.from_expansion),
- ))
-}
-
-/// Returns a span encompassing all the document fragments.
-pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
- span_of_fragments_with_expansion(fragments).map(|(sp, _)| sp)
+ Some(first_fragment.span.to(last_fragment.span))
}
/// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code.
@@ -686,7 +677,7 @@ pub fn source_span_for_markdown_range_inner(
}
}
- let (span, _) = span_of_fragments_with_expansion(fragments)?;
+ let span = span_of_fragments(fragments)?;
let src_span = span.from_inner(InnerSpan::new(
md_range.start + start_bytes,
md_range.end + start_bytes + end_bytes,
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 7bea868..8f624e0 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -343,12 +343,12 @@ pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
if let Some(component_to_enable) = component.strip_prefix('+') {
self.explicitly_set = None;
self.enabled_components
- .insert(LinkSelfContainedComponents::from_str(component_to_enable)?);
+ .insert(LinkSelfContainedComponents::from_str(component_to_enable).ok()?);
Some(())
} else if let Some(component_to_disable) = component.strip_prefix('-') {
self.explicitly_set = None;
self.disabled_components
- .insert(LinkSelfContainedComponents::from_str(component_to_disable)?);
+ .insert(LinkSelfContainedComponents::from_str(component_to_disable).ok()?);
Some(())
} else {
None
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index b33e381..5f1973b 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1296,7 +1296,7 @@ pub(crate) fn parse_mir_strip_debuginfo(slot: &mut MirStripDebugInfo, v: Option<
}
pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
- match v.and_then(LinkerFlavorCli::from_str) {
+ match v.and_then(|v| LinkerFlavorCli::from_str(v).ok()) {
Some(lf) => *slot = Some(lf),
_ => return false,
}
diff --git a/compiler/rustc_target/Cargo.toml b/compiler/rustc_target/Cargo.toml
index 0121c75..56932c2 100644
--- a/compiler/rustc_target/Cargo.toml
+++ b/compiler/rustc_target/Cargo.toml
@@ -12,7 +12,10 @@
rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
+serde = "1.0.219"
+serde_derive = "1.0.219"
serde_json = "1.0.59"
+serde_path_to_error = "0.1.17"
tracing = "0.1"
# tidy-alphabetical-end
diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs
index 4fcc477..896609b 100644
--- a/compiler/rustc_target/src/json.rs
+++ b/compiler/rustc_target/src/json.rs
@@ -114,3 +114,18 @@ fn to_json(&self) -> Json {
self.to_string().to_json()
}
}
+
+macro_rules! serde_deserialize_from_str {
+ ($ty:ty) => {
+ impl<'de> serde::Deserialize<'de> for $ty {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let s = String::deserialize(deserializer)?;
+ FromStr::from_str(&s).map_err(serde::de::Error::custom)
+ }
+ }
+ };
+}
+pub(crate) use serde_deserialize_from_str;
diff --git a/compiler/rustc_target/src/spec/json.rs b/compiler/rustc_target/src/spec/json.rs
index 6c716f8..d27c192 100644
--- a/compiler/rustc_target/src/spec/json.rs
+++ b/compiler/rustc_target/src/spec/json.rs
@@ -1,60 +1,47 @@
-use std::borrow::Cow;
use std::collections::BTreeMap;
use std::str::FromStr;
-use rustc_abi::{Align, AlignFromBytesError, ExternAbi};
-use serde_json::Value;
+use rustc_abi::{Align, AlignFromBytesError};
-use super::{Target, TargetKind, TargetOptions, TargetWarnings};
+use super::crt_objects::CrtObjects;
+use super::{
+ BinaryFormat, CodeModel, DebuginfoKind, FloatAbi, FramePointer, LinkArgsCli,
+ LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFlavorCli, LldFlavor,
+ MergeFunctions, PanicStrategy, RelocModel, RelroLevel, RustcAbi, SanitizerSet,
+ SmallDataThresholdSupport, SplitDebuginfo, StackProbeType, StaticCow, SymbolVisibility, Target,
+ TargetKind, TargetOptions, TargetWarnings, TlsModel,
+};
use crate::json::{Json, ToJson};
use crate::spec::AbiMap;
impl Target {
/// Loads a target descriptor from a JSON object.
- pub fn from_json(obj: Json) -> Result<(Target, TargetWarnings), String> {
- // While ugly, this code must remain this way to retain
- // compatibility with existing JSON fields and the internal
- // expected naming of the Target and TargetOptions structs.
- // To ensure compatibility is retained, the built-in targets
- // are round-tripped through this code to catch cases where
- // the JSON parser is not updated to match the structs.
+ pub fn from_json(json: &str) -> Result<(Target, TargetWarnings), String> {
+ let json_deserializer = &mut serde_json::Deserializer::from_str(json);
- let mut obj = match obj {
- Value::Object(obj) => obj,
- _ => return Err("Expected JSON object for target")?,
- };
-
- let mut get_req_field = |name: &str| {
- obj.remove(name)
- .and_then(|j| j.as_str().map(str::to_string))
- .ok_or_else(|| format!("Field {name} in target specification is required"))
- };
+ let json: TargetSpecJson =
+ serde_path_to_error::deserialize(json_deserializer).map_err(|err| err.to_string())?;
let mut base = Target {
- llvm_target: get_req_field("llvm-target")?.into(),
+ llvm_target: json.llvm_target,
metadata: Default::default(),
- pointer_width: get_req_field("target-pointer-width")?
- .parse::<u32>()
- .map_err(|_| "target-pointer-width must be an integer".to_string())?,
- data_layout: get_req_field("data-layout")?.into(),
- arch: get_req_field("arch")?.into(),
+ pointer_width: json
+ .target_pointer_width
+ .parse()
+ .map_err(|err| format!("invalid target-pointer-width: {err}"))?,
+ data_layout: json.data_layout,
+ arch: json.arch,
options: Default::default(),
};
// FIXME: This doesn't properly validate anything and just ignores the data if it's invalid.
// That's okay for now, the only use of this is when generating docs, which we don't do for
// custom targets.
- if let Some(Json::Object(mut metadata)) = obj.remove("metadata") {
- base.metadata.description = metadata
- .remove("description")
- .and_then(|desc| desc.as_str().map(|desc| desc.to_owned().into()));
- base.metadata.tier = metadata
- .remove("tier")
- .and_then(|tier| tier.as_u64())
- .filter(|tier| (1..=3).contains(tier));
- base.metadata.host_tools =
- metadata.remove("host_tools").and_then(|host| host.as_bool());
- base.metadata.std = metadata.remove("std").and_then(|host| host.as_bool());
+ if let Some(metadata) = json.metadata {
+ base.metadata.description = metadata.description;
+ base.metadata.tier = metadata.tier.filter(|tier| (1..=3).contains(tier));
+ base.metadata.host_tools = metadata.host_tools;
+ base.metadata.std = metadata.std;
}
let alignment_error = |field_name: &str, error: AlignFromBytesError| -> String {
@@ -65,640 +52,188 @@ pub fn from_json(obj: Json) -> Result<(Target, TargetWarnings), String> {
format!("`{}` bits is not a valid value for {field_name}: {msg}", error.align() * 8)
};
- let mut incorrect_type = vec![];
-
- macro_rules! key {
- ($key_name:ident) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(s) = obj.remove(&name).and_then(|s| s.as_str().map(str::to_string).map(Cow::from)) {
- base.$key_name = s;
+ macro_rules! forward {
+ ($name:ident) => {
+ if let Some($name) = json.$name {
+ base.$name = $name;
}
- } );
- ($key_name:ident = $json_name:expr) => ( {
- let name = $json_name;
- if let Some(s) = obj.remove(name).and_then(|s| s.as_str().map(str::to_string).map(Cow::from)) {
- base.$key_name = s;
+ };
+ }
+ macro_rules! forward_opt {
+ ($name:ident) => {
+ if let Some($name) = json.$name {
+ base.$name = Some($name);
}
- } );
- ($key_name:ident = $json_name:expr, u64 as $int_ty:ty) => ( {
- let name = $json_name;
- if let Some(s) = obj.remove(name).and_then(|b| b.as_u64()) {
- base.$key_name = s as $int_ty;
- }
- } );
- ($key_name:ident, bool) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) {
- base.$key_name = s;
- }
- } );
- ($key_name:ident = $json_name:expr, bool) => ( {
- let name = $json_name;
- if let Some(s) = obj.remove(name).and_then(|b| b.as_bool()) {
- base.$key_name = s;
- }
- } );
- ($key_name:ident, u32) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
- if s < 1 || s > 5 {
- return Err("Not a valid DWARF version number".into());
- }
- base.$key_name = s as u32;
- }
- } );
- ($key_name:ident, Option<bool>) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) {
- base.$key_name = Some(s);
- }
- } );
- ($key_name:ident, Option<u64>) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
- base.$key_name = Some(s);
- }
- } );
- ($key_name:ident, Option<StaticCow<str>>) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(s) = obj.remove(&name).and_then(|b| Some(b.as_str()?.to_string())) {
- base.$key_name = Some(s.into());
- }
- } );
- ($key_name:ident, Option<Align>) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(b) = obj.remove(&name).and_then(|b| b.as_u64()) {
- match Align::from_bits(b) {
- Ok(align) => base.$key_name = Some(align),
- Err(e) => return Err(alignment_error(&name, e)),
- }
- }
- } );
- ($key_name:ident, BinaryFormat) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|f| f.as_str().and_then(|s| {
- match s.parse::<super::BinaryFormat>() {
- Ok(binary_format) => base.$key_name = binary_format,
- _ => return Some(Err(format!(
- "'{s}' is not a valid value for binary_format. \
- Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' "
- ))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, MergeFunctions) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::MergeFunctions>() {
- Ok(mergefunc) => base.$key_name = mergefunc,
- _ => return Some(Err(format!("'{}' is not a valid value for \
- merge-functions. Use 'disabled', \
- 'trampolines', or 'aliases'.",
- s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, FloatAbi) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::FloatAbi>() {
- Ok(float_abi) => base.$key_name = Some(float_abi),
- _ => return Some(Err(format!("'{}' is not a valid value for \
- llvm-floatabi. Use 'soft' or 'hard'.",
- s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, RustcAbi) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::RustcAbi>() {
- Ok(rustc_abi) => base.$key_name = Some(rustc_abi),
- _ => return Some(Err(format!(
- "'{s}' is not a valid value for rustc-abi. \
- Use 'x86-softfloat' or leave the field unset."
- ))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, RelocModel) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::RelocModel>() {
- Ok(relocation_model) => base.$key_name = relocation_model,
- _ => return Some(Err(format!("'{}' is not a valid relocation model. \
- Run `rustc --print relocation-models` to \
- see the list of supported values.", s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, CodeModel) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::CodeModel>() {
- Ok(code_model) => base.$key_name = Some(code_model),
- _ => return Some(Err(format!("'{}' is not a valid code model. \
- Run `rustc --print code-models` to \
- see the list of supported values.", s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, TlsModel) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::TlsModel>() {
- Ok(tls_model) => base.$key_name = tls_model,
- _ => return Some(Err(format!("'{}' is not a valid TLS model. \
- Run `rustc --print tls-models` to \
- see the list of supported values.", s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, SmallDataThresholdSupport) => ( {
- obj.remove("small-data-threshold-support").and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::SmallDataThresholdSupport>() {
- Ok(support) => base.small_data_threshold_support = support,
- _ => return Some(Err(format!("'{s}' is not a valid value for small-data-threshold-support."))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, PanicStrategy) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s {
- "unwind" => base.$key_name = super::PanicStrategy::Unwind,
- "abort" => base.$key_name = super::PanicStrategy::Abort,
- _ => return Some(Err(format!("'{}' is not a valid value for \
- panic-strategy. Use 'unwind' or 'abort'.",
- s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, RelroLevel) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::RelroLevel>() {
- Ok(level) => base.$key_name = level,
- _ => return Some(Err(format!("'{}' is not a valid value for \
- relro-level. Use 'full', 'partial, or 'off'.",
- s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, Option<SymbolVisibility>) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::SymbolVisibility>() {
- Ok(level) => base.$key_name = Some(level),
- _ => return Some(Err(format!("'{}' is not a valid value for \
- symbol-visibility. Use 'hidden', 'protected, or 'interposable'.",
- s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, DebuginfoKind) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::DebuginfoKind>() {
- Ok(level) => base.$key_name = level,
- _ => return Some(Err(
- format!("'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \
- 'dwarf-dsym' or 'pdb'.")
- )),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, SplitDebuginfo) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::SplitDebuginfo>() {
- Ok(level) => base.$key_name = level,
- _ => return Some(Err(format!("'{}' is not a valid value for \
- split-debuginfo. Use 'off' or 'dsymutil'.",
- s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, list) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(j) = obj.remove(&name) {
- if let Some(v) = j.as_array() {
- base.$key_name = v.iter()
- .map(|a| a.as_str().unwrap().to_string().into())
- .collect();
- } else {
- incorrect_type.push(name)
- }
- }
- } );
- ($key_name:ident, opt_list) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(j) = obj.remove(&name) {
- if let Some(v) = j.as_array() {
- base.$key_name = Some(v.iter()
- .map(|a| a.as_str().unwrap().to_string().into())
- .collect());
- } else {
- incorrect_type.push(name)
- }
- }
- } );
- ($key_name:ident, fallible_list) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|j| {
- if let Some(v) = j.as_array() {
- match v.iter().map(|a| FromStr::from_str(a.as_str().unwrap())).collect() {
- Ok(l) => { base.$key_name = l },
- // FIXME: `fallible_list` can't re-use the `key!` macro for list
- // elements and the error messages from that macro, so it has a bad
- // generic message instead
- Err(_) => return Some(Err(
- format!("`{:?}` is not a valid value for `{}`", j, name)
- )),
- }
- } else {
- incorrect_type.push(name)
- }
- Some(Ok(()))
- }).unwrap_or(Ok(()))
- } );
- ($key_name:ident, optional) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(o) = obj.remove(&name) {
- base.$key_name = o
- .as_str()
- .map(|s| s.to_string().into());
- }
- } );
- ($key_name:ident = $json_name:expr, LldFlavor) => ( {
- let name = $json_name;
- obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
- if let Some(flavor) = super::LldFlavor::from_str(&s) {
- base.$key_name = flavor;
- } else {
- return Some(Err(format!(
- "'{}' is not a valid value for lld-flavor. \
- Use 'darwin', 'gnu', 'link' or 'wasm'.",
- s)))
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident = $json_name:expr, LinkerFlavorCli) => ( {
- let name = $json_name;
- obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
- match super::LinkerFlavorCli::from_str(s) {
- Some(linker_flavor) => base.$key_name = linker_flavor,
- _ => return Some(Err(format!("'{}' is not a valid value for linker-flavor. \
- Use {}", s, super::LinkerFlavorCli::one_of()))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident, StackProbeType) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- obj.remove(&name).and_then(|o| match super::StackProbeType::from_json(&o) {
- Ok(v) => {
- base.$key_name = v;
- Some(Ok(()))
- },
- Err(s) => Some(Err(
- format!("`{:?}` is not a valid value for `{}`: {}", o, name, s)
- )),
- }).unwrap_or(Ok(()))
- } );
- ($key_name:ident, SanitizerSet) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(o) = obj.remove(&name) {
- if let Some(a) = o.as_array() {
- for s in a {
- use super::SanitizerSet;
- base.$key_name |= match s.as_str() {
- Some("address") => SanitizerSet::ADDRESS,
- Some("cfi") => SanitizerSet::CFI,
- Some("dataflow") => SanitizerSet::DATAFLOW,
- Some("kcfi") => SanitizerSet::KCFI,
- Some("kernel-address") => SanitizerSet::KERNELADDRESS,
- Some("leak") => SanitizerSet::LEAK,
- Some("memory") => SanitizerSet::MEMORY,
- Some("memtag") => SanitizerSet::MEMTAG,
- Some("safestack") => SanitizerSet::SAFESTACK,
- Some("shadow-call-stack") => SanitizerSet::SHADOWCALLSTACK,
- Some("thread") => SanitizerSet::THREAD,
- Some("hwaddress") => SanitizerSet::HWADDRESS,
- Some(s) => return Err(format!("unknown sanitizer {}", s)),
- _ => return Err(format!("not a string: {:?}", s)),
- };
- }
- } else {
- incorrect_type.push(name)
- }
- }
- Ok::<(), String>(())
- } );
- ($key_name:ident, link_self_contained_components) => ( {
- // Skeleton of what needs to be parsed:
- //
- // ```
- // $name: {
- // "components": [
- // <array of strings>
- // ]
- // }
- // ```
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(o) = obj.remove(&name) {
- if let Some(o) = o.as_object() {
- let component_array = o.get("components")
- .ok_or_else(|| format!("{name}: expected a \
- JSON object with a `components` field."))?;
- let component_array = component_array.as_array()
- .ok_or_else(|| format!("{name}.components: expected a JSON array"))?;
- let mut components = super::LinkSelfContainedComponents::empty();
- for s in component_array {
- components |= match s.as_str() {
- Some(s) => {
- super::LinkSelfContainedComponents::from_str(s)
- .ok_or_else(|| format!("unknown \
- `-Clink-self-contained` component: {s}"))?
- },
- _ => return Err(format!("not a string: {:?}", s)),
- };
- }
- base.$key_name = super::LinkSelfContainedDefault::WithComponents(components);
- } else {
- incorrect_type.push(name)
- }
- }
- Ok::<(), String>(())
- } );
- ($key_name:ident = $json_name:expr, link_self_contained_backwards_compatible) => ( {
- let name = $json_name;
- obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
- match s.parse::<super::LinkSelfContainedDefault>() {
- Ok(lsc_default) => base.$key_name = lsc_default,
- _ => return Some(Err(format!("'{}' is not a valid `-Clink-self-contained` default. \
- Use 'false', 'true', 'musl' or 'mingw'", s))),
- }
- Some(Ok(()))
- })).unwrap_or(Ok(()))
- } );
- ($key_name:ident = $json_name:expr, link_objects) => ( {
- let name = $json_name;
- if let Some(val) = obj.remove(name) {
- let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
- JSON object with fields per CRT object kind.", name))?;
- let mut args = super::CrtObjects::new();
- for (k, v) in obj {
- let kind = super::LinkOutputKind::from_str(&k).ok_or_else(|| {
- format!("{}: '{}' is not a valid value for CRT object kind. \
- Use '(dynamic,static)-(nopic,pic)-exe' or \
- '(dynamic,static)-dylib' or 'wasi-reactor-exe'", name, k)
- })?;
-
- let v = v.as_array().ok_or_else(||
- format!("{}.{}: expected a JSON array", name, k)
- )?.iter().enumerate()
- .map(|(i,s)| {
- let s = s.as_str().ok_or_else(||
- format!("{}.{}[{}]: expected a JSON string", name, k, i))?;
- Ok(s.to_string().into())
- })
- .collect::<Result<Vec<_>, String>>()?;
-
- args.insert(kind, v);
- }
- base.$key_name = args;
- }
- } );
- ($key_name:ident = $json_name:expr, link_args) => ( {
- let name = $json_name;
- if let Some(val) = obj.remove(name) {
- let obj = val.as_object().ok_or_else(|| format!("{}: expected a \
- JSON object with fields per linker-flavor.", name))?;
- let mut args = super::LinkArgsCli::new();
- for (k, v) in obj {
- let flavor = super::LinkerFlavorCli::from_str(&k).ok_or_else(|| {
- format!("{}: '{}' is not a valid value for linker-flavor. \
- Use 'em', 'gcc', 'ld' or 'msvc'", name, k)
- })?;
-
- let v = v.as_array().ok_or_else(||
- format!("{}.{}: expected a JSON array", name, k)
- )?.iter().enumerate()
- .map(|(i,s)| {
- let s = s.as_str().ok_or_else(||
- format!("{}.{}[{}]: expected a JSON string", name, k, i))?;
- Ok(s.to_string().into())
- })
- .collect::<Result<Vec<_>, String>>()?;
-
- args.insert(flavor, v);
- }
- base.$key_name = args;
- }
- } );
- ($key_name:ident, env) => ( {
- let name = (stringify!($key_name)).replace("_", "-");
- if let Some(o) = obj.remove(&name) {
- if let Some(a) = o.as_array() {
- for o in a {
- if let Some(s) = o.as_str() {
- if let [k, v] = *s.split('=').collect::<Vec<_>>() {
- base.$key_name
- .to_mut()
- .push((k.to_string().into(), v.to_string().into()))
- }
- }
- }
- } else {
- incorrect_type.push(name)
- }
- }
- } );
- ($key_name:ident, target_families) => ( {
- if let Some(value) = obj.remove("target-family") {
- if let Some(v) = value.as_array() {
- base.$key_name = v.iter()
- .map(|a| a.as_str().unwrap().to_string().into())
- .collect();
- } else if let Some(v) = value.as_str() {
- base.$key_name = vec![v.to_string().into()].into();
- }
- }
- } );
+ };
}
- if let Some(j) = obj.remove("target-endian") {
- if let Some(s) = j.as_str() {
- base.endian = s.parse()?;
- } else {
- incorrect_type.push("target-endian".into())
- }
+ if let Some(target_endian) = json.target_endian {
+ base.endian = target_endian.0;
}
- if let Some(fp) = obj.remove("frame-pointer") {
- if let Some(s) = fp.as_str() {
- base.frame_pointer = s
- .parse()
- .map_err(|()| format!("'{s}' is not a valid value for frame-pointer"))?;
- } else {
- incorrect_type.push("frame-pointer".into())
- }
- }
+ forward!(frame_pointer);
+ forward!(c_int_width);
+ forward_opt!(c_enum_min_bits); // if None, matches c_int_width
+ forward!(os);
+ forward!(env);
+ forward!(abi);
+ forward!(vendor);
+ forward_opt!(linker);
+ forward!(linker_flavor_json);
+ forward!(lld_flavor_json);
+ forward!(linker_is_gnu_json);
+ forward!(pre_link_objects);
+ forward!(post_link_objects);
+ forward!(pre_link_objects_self_contained);
+ forward!(post_link_objects_self_contained);
- key!(c_int_width = "target-c-int-width", u64 as u16);
- key!(c_enum_min_bits, Option<u64>); // if None, matches c_int_width
- key!(os);
- key!(env);
- key!(abi);
- key!(vendor);
- key!(linker, optional);
- key!(linker_flavor_json = "linker-flavor", LinkerFlavorCli)?;
- key!(lld_flavor_json = "lld-flavor", LldFlavor)?;
- key!(linker_is_gnu_json = "linker-is-gnu", bool);
- key!(pre_link_objects = "pre-link-objects", link_objects);
- key!(post_link_objects = "post-link-objects", link_objects);
- key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects);
- key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects);
// Deserializes the backwards-compatible variants of `-Clink-self-contained`
- key!(
- link_self_contained = "crt-objects-fallback",
- link_self_contained_backwards_compatible
- )?;
+ if let Some(link_self_contained) = json.link_self_contained_backwards_compatible {
+ base.link_self_contained = link_self_contained;
+ }
// Deserializes the components variant of `-Clink-self-contained`
- key!(link_self_contained, link_self_contained_components)?;
- key!(pre_link_args_json = "pre-link-args", link_args);
- key!(late_link_args_json = "late-link-args", link_args);
- key!(late_link_args_dynamic_json = "late-link-args-dynamic", link_args);
- key!(late_link_args_static_json = "late-link-args-static", link_args);
- key!(post_link_args_json = "post-link-args", link_args);
- key!(link_script, optional);
- key!(link_env, env);
- key!(link_env_remove, list);
- key!(asm_args, list);
- key!(cpu);
- key!(need_explicit_cpu, bool);
- key!(features);
- key!(dynamic_linking, bool);
- key!(direct_access_external_data, Option<bool>);
- key!(dll_tls_export, bool);
- key!(only_cdylib, bool);
- key!(executables, bool);
- key!(relocation_model, RelocModel)?;
- key!(code_model, CodeModel)?;
- key!(tls_model, TlsModel)?;
- key!(disable_redzone, bool);
- key!(function_sections, bool);
- key!(dll_prefix);
- key!(dll_suffix);
- key!(exe_suffix);
- key!(staticlib_prefix);
- key!(staticlib_suffix);
- key!(families, target_families);
- key!(abi_return_struct_as_int, bool);
- key!(is_like_aix, bool);
- key!(is_like_darwin, bool);
- key!(is_like_solaris, bool);
- key!(is_like_windows, bool);
- key!(is_like_msvc, bool);
- key!(is_like_wasm, bool);
- key!(is_like_android, bool);
- key!(binary_format, BinaryFormat)?;
- key!(default_dwarf_version, u32);
- key!(allows_weak_linkage, bool);
- key!(has_rpath, bool);
- key!(no_default_libraries, bool);
- key!(position_independent_executables, bool);
- key!(static_position_independent_executables, bool);
- key!(plt_by_default, bool);
- key!(relro_level, RelroLevel)?;
- key!(archive_format);
- key!(allow_asm, bool);
- key!(main_needs_argc_argv, bool);
- key!(has_thread_local, bool);
- key!(obj_is_bitcode, bool);
- key!(bitcode_llvm_cmdline);
- key!(max_atomic_width, Option<u64>);
- key!(min_atomic_width, Option<u64>);
- key!(atomic_cas, bool);
- key!(panic_strategy, PanicStrategy)?;
- key!(crt_static_allows_dylibs, bool);
- key!(crt_static_default, bool);
- key!(crt_static_respected, bool);
- key!(stack_probes, StackProbeType)?;
- key!(min_global_align, Option<Align>);
- key!(default_codegen_units, Option<u64>);
- key!(default_codegen_backend, Option<StaticCow<str>>);
- key!(trap_unreachable, bool);
- key!(requires_lto, bool);
- key!(singlethread, bool);
- key!(no_builtins, bool);
- key!(default_visibility, Option<SymbolVisibility>)?;
- key!(emit_debug_gdb_scripts, bool);
- key!(requires_uwtable, bool);
- key!(default_uwtable, bool);
- key!(simd_types_indirect, bool);
- key!(limit_rdylib_exports, bool);
- key!(override_export_symbols, opt_list);
- key!(merge_functions, MergeFunctions)?;
- key!(mcount = "target-mcount");
- key!(llvm_mcount_intrinsic, optional);
- key!(llvm_abiname);
- key!(llvm_floatabi, FloatAbi)?;
- key!(rustc_abi, RustcAbi)?;
- key!(relax_elf_relocations, bool);
- key!(llvm_args, list);
- key!(use_ctors_section, bool);
- key!(eh_frame_header, bool);
- key!(has_thumb_interworking, bool);
- key!(debuginfo_kind, DebuginfoKind)?;
- key!(split_debuginfo, SplitDebuginfo)?;
- key!(supported_split_debuginfo, fallible_list)?;
- key!(supported_sanitizers, SanitizerSet)?;
- key!(generate_arange_section, bool);
- key!(supports_stack_protector, bool);
- key!(small_data_threshold_support, SmallDataThresholdSupport)?;
- key!(entry_name);
- key!(supports_xray, bool);
+ if let Some(link_self_contained) = json.link_self_contained {
+ let components = link_self_contained
+ .components
+ .into_iter()
+ .fold(LinkSelfContainedComponents::empty(), |a, b| a | b);
+ base.link_self_contained = LinkSelfContainedDefault::WithComponents(components);
+ }
+
+ forward!(pre_link_args_json);
+ forward!(late_link_args_json);
+ forward!(late_link_args_dynamic_json);
+ forward!(late_link_args_static_json);
+ forward!(post_link_args_json);
+ forward_opt!(link_script);
+
+ if let Some(link_env) = json.link_env {
+ for s in link_env {
+ if let [k, v] = *s.split('=').collect::<Vec<_>>() {
+ base.link_env.to_mut().push((k.to_string().into(), v.to_string().into()))
+ } else {
+ return Err(format!("link-env value '{s}' must be of the pattern 'KEY=VALUE'"));
+ }
+ }
+ }
+
+ forward!(link_env_remove);
+ forward!(asm_args);
+ forward!(cpu);
+ forward!(need_explicit_cpu);
+ forward!(features);
+ forward!(dynamic_linking);
+ forward_opt!(direct_access_external_data);
+ forward!(dll_tls_export);
+ forward!(only_cdylib);
+ forward!(executables);
+ forward!(relocation_model);
+ forward_opt!(code_model);
+ forward!(tls_model);
+ forward!(disable_redzone);
+ forward!(function_sections);
+ forward!(dll_prefix);
+ forward!(dll_suffix);
+ forward!(exe_suffix);
+ forward!(staticlib_prefix);
+ forward!(staticlib_suffix);
+
+ if let Some(target_family) = json.target_family {
+ match target_family {
+ TargetFamiliesJson::Array(families) => base.families = families,
+ TargetFamiliesJson::String(family) => base.families = vec![family].into(),
+ }
+ }
+
+ forward!(abi_return_struct_as_int);
+ forward!(is_like_aix);
+ forward!(is_like_darwin);
+ forward!(is_like_solaris);
+ forward!(is_like_windows);
+ forward!(is_like_msvc);
+ forward!(is_like_wasm);
+ forward!(is_like_android);
+ forward!(binary_format);
+ forward!(default_dwarf_version);
+ forward!(allows_weak_linkage);
+ forward!(has_rpath);
+ forward!(no_default_libraries);
+ forward!(position_independent_executables);
+ forward!(static_position_independent_executables);
+ forward!(plt_by_default);
+ forward!(relro_level);
+ forward!(archive_format);
+ forward!(allow_asm);
+ forward!(main_needs_argc_argv);
+ forward!(has_thread_local);
+ forward!(obj_is_bitcode);
+ forward!(bitcode_llvm_cmdline);
+ forward_opt!(max_atomic_width);
+ forward_opt!(min_atomic_width);
+ forward!(atomic_cas);
+ forward!(panic_strategy);
+ forward!(crt_static_allows_dylibs);
+ forward!(crt_static_default);
+ forward!(crt_static_respected);
+ forward!(stack_probes);
+
+ if let Some(min_global_align) = json.min_global_align {
+ match Align::from_bits(min_global_align) {
+ Ok(align) => base.min_global_align = Some(align),
+ Err(e) => return Err(alignment_error("min-global-align", e)),
+ }
+ }
+
+ forward_opt!(default_codegen_units);
+ forward_opt!(default_codegen_backend);
+ forward!(trap_unreachable);
+ forward!(requires_lto);
+ forward!(singlethread);
+ forward!(no_builtins);
+ forward_opt!(default_visibility);
+ forward!(emit_debug_gdb_scripts);
+ forward!(requires_uwtable);
+ forward!(default_uwtable);
+ forward!(simd_types_indirect);
+ forward!(limit_rdylib_exports);
+ forward_opt!(override_export_symbols);
+ forward!(merge_functions);
+ forward!(mcount);
+ forward_opt!(llvm_mcount_intrinsic);
+ forward!(llvm_abiname);
+ forward_opt!(llvm_floatabi);
+ forward_opt!(rustc_abi);
+ forward!(relax_elf_relocations);
+ forward!(llvm_args);
+ forward!(use_ctors_section);
+ forward!(eh_frame_header);
+ forward!(has_thumb_interworking);
+ forward!(debuginfo_kind);
+ forward!(split_debuginfo);
+ forward!(supported_split_debuginfo);
+
+ if let Some(supported_sanitizers) = json.supported_sanitizers {
+ base.supported_sanitizers =
+ supported_sanitizers.into_iter().fold(SanitizerSet::empty(), |a, b| a | b);
+ }
+
+ forward!(generate_arange_section);
+ forward!(supports_stack_protector);
+ forward!(small_data_threshold_support);
+ forward!(entry_name);
+ forward!(supports_xray);
// we're going to run `update_from_cli`, but that won't change the target's AbiMap
// FIXME: better factor the Target definition so we enforce this on a type level
let abi_map = AbiMap::from_target(&base);
-
- if let Some(abi_str) = obj.remove("entry-abi") {
- if let Json::String(abi_str) = abi_str {
- match abi_str.parse::<ExternAbi>() {
- Ok(abi) => base.options.entry_abi = abi_map.canonize_abi(abi, false).unwrap(),
- Err(_) => return Err(format!("{abi_str} is not a valid ExternAbi")),
- }
- } else {
- incorrect_type.push("entry-abi".to_owned())
- }
+ if let Some(entry_abi) = json.entry_abi {
+ base.options.entry_abi = abi_map.canonize_abi(entry_abi.0, false).unwrap();
}
base.update_from_cli();
base.check_consistency(TargetKind::Json)?;
- // Each field should have been read using `Json::remove` so any keys remaining are unused.
- let remaining_keys = obj.keys();
- Ok((
- base,
- TargetWarnings { unused_fields: remaining_keys.cloned().collect(), incorrect_type },
- ))
+ Ok((base, TargetWarnings { unused_fields: vec![] }))
}
}
@@ -877,3 +412,189 @@ macro_rules! target_option_val {
Json::Object(d)
}
}
+
+#[derive(serde_derive::Deserialize)]
+struct LinkSelfContainedComponentsWrapper {
+ components: Vec<LinkSelfContainedComponents>,
+}
+
+#[derive(serde_derive::Deserialize)]
+#[serde(untagged)]
+enum TargetFamiliesJson {
+ Array(StaticCow<[StaticCow<str>]>),
+ String(StaticCow<str>),
+}
+
+/// `Endian` is in `rustc_abi`, which doesn't have access to the macro and serde.
+struct EndianWrapper(rustc_abi::Endian);
+impl FromStr for EndianWrapper {
+ type Err = String;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ rustc_abi::Endian::from_str(s).map(Self)
+ }
+}
+crate::json::serde_deserialize_from_str!(EndianWrapper);
+
+/// `ExternAbi` is in `rustc_abi`, which doesn't have access to the macro and serde.
+struct ExternAbiWrapper(rustc_abi::ExternAbi);
+impl FromStr for ExternAbiWrapper {
+ type Err = String;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ rustc_abi::ExternAbi::from_str(s)
+ .map(Self)
+ .map_err(|_| format!("{s} is not a valid extern ABI"))
+ }
+}
+crate::json::serde_deserialize_from_str!(ExternAbiWrapper);
+
+#[derive(serde_derive::Deserialize)]
+struct TargetSpecJsonMetadata {
+ description: Option<StaticCow<str>>,
+ tier: Option<u64>,
+ host_tools: Option<bool>,
+ std: Option<bool>,
+}
+
+#[derive(serde_derive::Deserialize)]
+#[serde(rename_all = "kebab-case")]
+// Ensure that all unexpected fields get turned into errors.
+// This helps users stay up to date when the schema changes instead of silently
+// ignoring their old values.
+#[serde(deny_unknown_fields)]
+struct TargetSpecJson {
+ llvm_target: StaticCow<str>,
+ target_pointer_width: String,
+ data_layout: StaticCow<str>,
+ arch: StaticCow<str>,
+
+ metadata: Option<TargetSpecJsonMetadata>,
+
+ // options:
+ target_endian: Option<EndianWrapper>,
+ frame_pointer: Option<FramePointer>,
+ #[serde(rename = "target-c-int-width")]
+ c_int_width: Option<u16>,
+ c_enum_min_bits: Option<u64>,
+ os: Option<StaticCow<str>>,
+ env: Option<StaticCow<str>>,
+ abi: Option<StaticCow<str>>,
+ vendor: Option<StaticCow<str>>,
+ linker: Option<StaticCow<str>>,
+ #[serde(rename = "linker-flavor")]
+ linker_flavor_json: Option<LinkerFlavorCli>,
+ #[serde(rename = "lld-flavor")]
+ lld_flavor_json: Option<LldFlavor>,
+ #[serde(rename = "linker-is-gnu")]
+ linker_is_gnu_json: Option<bool>,
+ #[serde(rename = "pre-link-objects")]
+ pre_link_objects: Option<CrtObjects>,
+ #[serde(rename = "post-link-objects")]
+ post_link_objects: Option<CrtObjects>,
+ #[serde(rename = "pre-link-objects-fallback")]
+ pre_link_objects_self_contained: Option<CrtObjects>,
+ #[serde(rename = "post-link-objects-fallback")]
+ post_link_objects_self_contained: Option<CrtObjects>,
+ #[serde(rename = "crt-objects-fallback")]
+ link_self_contained_backwards_compatible: Option<LinkSelfContainedDefault>,
+ link_self_contained: Option<LinkSelfContainedComponentsWrapper>,
+ #[serde(rename = "pre-link-args")]
+ pre_link_args_json: Option<LinkArgsCli>,
+ #[serde(rename = "late-link-args")]
+ late_link_args_json: Option<LinkArgsCli>,
+ #[serde(rename = "late-link-args-dynamic")]
+ late_link_args_dynamic_json: Option<LinkArgsCli>,
+ #[serde(rename = "late-link-args-static")]
+ late_link_args_static_json: Option<LinkArgsCli>,
+ #[serde(rename = "post-link-args")]
+ post_link_args_json: Option<LinkArgsCli>,
+ link_script: Option<StaticCow<str>>,
+ link_env: Option<Vec<StaticCow<str>>>,
+ link_env_remove: Option<StaticCow<[StaticCow<str>]>>,
+ asm_args: Option<StaticCow<[StaticCow<str>]>>,
+ cpu: Option<StaticCow<str>>,
+ need_explicit_cpu: Option<bool>,
+ features: Option<StaticCow<str>>,
+ dynamic_linking: Option<bool>,
+ direct_access_external_data: Option<bool>,
+ dll_tls_export: Option<bool>,
+ only_cdylib: Option<bool>,
+ executables: Option<bool>,
+ relocation_model: Option<RelocModel>,
+ code_model: Option<CodeModel>,
+ tls_model: Option<TlsModel>,
+ disable_redzone: Option<bool>,
+ function_sections: Option<bool>,
+ dll_prefix: Option<StaticCow<str>>,
+ dll_suffix: Option<StaticCow<str>>,
+ exe_suffix: Option<StaticCow<str>>,
+ staticlib_prefix: Option<StaticCow<str>>,
+ staticlib_suffix: Option<StaticCow<str>>,
+ target_family: Option<TargetFamiliesJson>,
+ abi_return_struct_as_int: Option<bool>,
+ is_like_aix: Option<bool>,
+ is_like_darwin: Option<bool>,
+ is_like_solaris: Option<bool>,
+ is_like_windows: Option<bool>,
+ is_like_msvc: Option<bool>,
+ is_like_wasm: Option<bool>,
+ is_like_android: Option<bool>,
+ binary_format: Option<BinaryFormat>,
+ default_dwarf_version: Option<u32>,
+ allows_weak_linkage: Option<bool>,
+ has_rpath: Option<bool>,
+ no_default_libraries: Option<bool>,
+ position_independent_executables: Option<bool>,
+ static_position_independent_executables: Option<bool>,
+ plt_by_default: Option<bool>,
+ relro_level: Option<RelroLevel>,
+ archive_format: Option<StaticCow<str>>,
+ allow_asm: Option<bool>,
+ main_needs_argc_argv: Option<bool>,
+ has_thread_local: Option<bool>,
+ obj_is_bitcode: Option<bool>,
+ bitcode_llvm_cmdline: Option<StaticCow<str>>,
+ max_atomic_width: Option<u64>,
+ min_atomic_width: Option<u64>,
+ atomic_cas: Option<bool>,
+ panic_strategy: Option<PanicStrategy>,
+ crt_static_allows_dylibs: Option<bool>,
+ crt_static_default: Option<bool>,
+ crt_static_respected: Option<bool>,
+ stack_probes: Option<StackProbeType>,
+ min_global_align: Option<u64>,
+ default_codegen_units: Option<u64>,
+ default_codegen_backend: Option<StaticCow<str>>,
+ trap_unreachable: Option<bool>,
+ requires_lto: Option<bool>,
+ singlethread: Option<bool>,
+ no_builtins: Option<bool>,
+ default_visibility: Option<SymbolVisibility>,
+ emit_debug_gdb_scripts: Option<bool>,
+ requires_uwtable: Option<bool>,
+ default_uwtable: Option<bool>,
+ simd_types_indirect: Option<bool>,
+ limit_rdylib_exports: Option<bool>,
+ override_export_symbols: Option<StaticCow<[StaticCow<str>]>>,
+ merge_functions: Option<MergeFunctions>,
+ #[serde(rename = "target-mcount")]
+ mcount: Option<StaticCow<str>>,
+ llvm_mcount_intrinsic: Option<StaticCow<str>>,
+ llvm_abiname: Option<StaticCow<str>>,
+ llvm_floatabi: Option<FloatAbi>,
+ rustc_abi: Option<RustcAbi>,
+ relax_elf_relocations: Option<bool>,
+ llvm_args: Option<StaticCow<[StaticCow<str>]>>,
+ use_ctors_section: Option<bool>,
+ eh_frame_header: Option<bool>,
+ has_thumb_interworking: Option<bool>,
+ debuginfo_kind: Option<DebuginfoKind>,
+ split_debuginfo: Option<SplitDebuginfo>,
+ supported_split_debuginfo: Option<StaticCow<[SplitDebuginfo]>>,
+ supported_sanitizers: Option<Vec<SanitizerSet>>,
+ generate_arange_section: Option<bool>,
+ supports_stack_protector: Option<bool>,
+ small_data_threshold_support: Option<SmallDataThresholdSupport>,
+ entry_name: Option<StaticCow<str>>,
+ supports_xray: Option<bool>,
+ entry_abi: Option<ExternAbiWrapper>,
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 4bc0d88..c64cd9a 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -37,6 +37,7 @@
//!
//! [JSON]: https://json.org
+use core::result::Result;
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::hash::{Hash, Hasher};
@@ -198,18 +199,29 @@ pub fn as_str(&self) -> &'static str {
LldFlavor::Link => "link",
}
}
+}
- fn from_str(s: &str) -> Option<Self> {
- Some(match s {
+impl FromStr for LldFlavor {
+ type Err = String;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
"darwin" => LldFlavor::Ld64,
"gnu" => LldFlavor::Ld,
"link" => LldFlavor::Link,
"wasm" => LldFlavor::Wasm,
- _ => return None,
+ _ => {
+ return Err(
+ "invalid value for lld flavor: '{s}', expected one of 'darwin', 'gnu', 'link', 'wasm'"
+ .into(),
+ );
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(LldFlavor);
+
impl ToJson for LldFlavor {
fn to_json(&self) -> Json {
self.as_str().to_json()
@@ -494,19 +506,23 @@ pub const fn one_of() -> &'static str {
concat!("one of: ", $($string, " ",)*)
}
- pub fn from_str(s: &str) -> Option<LinkerFlavorCli> {
- Some(match s {
- $($string => $($flavor)*,)*
- _ => return None,
- })
- }
-
pub fn desc(self) -> &'static str {
match self {
$($($flavor)* => $string,)*
}
}
}
+
+ impl FromStr for LinkerFlavorCli {
+ type Err = String;
+
+ fn from_str(s: &str) -> Result<LinkerFlavorCli, Self::Err> {
+ Ok(match s {
+ $($string => $($flavor)*,)*
+ _ => return Err(format!("invalid linker flavor, allowed values: {}", Self::one_of())),
+ })
+ }
+ }
)
}
@@ -540,6 +556,8 @@ pub fn desc(self) -> &'static str {
(LinkerFlavorCli::Em) "em"
}
+crate::json::serde_deserialize_from_str!(LinkerFlavorCli);
+
impl ToJson for LinkerFlavorCli {
fn to_json(&self) -> Json {
self.desc().to_json()
@@ -573,19 +591,26 @@ pub enum LinkSelfContainedDefault {
/// Parses a backwards-compatible `-Clink-self-contained` option string, without components.
impl FromStr for LinkSelfContainedDefault {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<LinkSelfContainedDefault, ()> {
+ fn from_str(s: &str) -> Result<LinkSelfContainedDefault, Self::Err> {
Ok(match s {
"false" => LinkSelfContainedDefault::False,
"true" | "wasm" => LinkSelfContainedDefault::True,
"musl" => LinkSelfContainedDefault::InferredForMusl,
"mingw" => LinkSelfContainedDefault::InferredForMingw,
- _ => return Err(()),
+ _ => {
+ return Err(format!(
+ "'{s}' is not a valid `-Clink-self-contained` default. \
+ Use 'false', 'true', 'wasm', 'musl' or 'mingw'",
+ ));
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(LinkSelfContainedDefault);
+
impl ToJson for LinkSelfContainedDefault {
fn to_json(&self) -> Json {
match *self {
@@ -652,19 +677,6 @@ pub struct LinkSelfContainedComponents: u8 {
rustc_data_structures::external_bitflags_debug! { LinkSelfContainedComponents }
impl LinkSelfContainedComponents {
- /// Parses a single `-Clink-self-contained` well-known component, not a set of flags.
- pub fn from_str(s: &str) -> Option<LinkSelfContainedComponents> {
- Some(match s {
- "crto" => LinkSelfContainedComponents::CRT_OBJECTS,
- "libc" => LinkSelfContainedComponents::LIBC,
- "unwind" => LinkSelfContainedComponents::UNWIND,
- "linker" => LinkSelfContainedComponents::LINKER,
- "sanitizers" => LinkSelfContainedComponents::SANITIZERS,
- "mingw" => LinkSelfContainedComponents::MINGW,
- _ => return None,
- })
- }
-
/// Return the component's name.
///
/// Returns `None` if the bitflags aren't a singular component (but a mix of multiple flags).
@@ -708,6 +720,29 @@ pub fn is_crt_objects_enabled(self) -> bool {
}
}
+impl FromStr for LinkSelfContainedComponents {
+ type Err = String;
+
+ /// Parses a single `-Clink-self-contained` well-known component, not a set of flags.
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "crto" => LinkSelfContainedComponents::CRT_OBJECTS,
+ "libc" => LinkSelfContainedComponents::LIBC,
+ "unwind" => LinkSelfContainedComponents::UNWIND,
+ "linker" => LinkSelfContainedComponents::LINKER,
+ "sanitizers" => LinkSelfContainedComponents::SANITIZERS,
+ "mingw" => LinkSelfContainedComponents::MINGW,
+ _ => {
+ return Err(format!(
+ "'{s}' is not a valid link-self-contained component, expected 'crto', 'libc', 'unwind', 'linker', 'sanitizers', 'mingw'"
+ ));
+ }
+ })
+ }
+}
+
+crate::json::serde_deserialize_from_str!(LinkSelfContainedComponents);
+
impl ToJson for LinkSelfContainedComponents {
fn to_json(&self) -> Json {
let components: Vec<_> = Self::all_components()
@@ -821,6 +856,25 @@ pub const fn desc_symbol(&self) -> Symbol {
}
}
+impl FromStr for PanicStrategy {
+ type Err = String;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "unwind" => PanicStrategy::Unwind,
+ "abort" => PanicStrategy::Abort,
+ _ => {
+ return Err(format!(
+ "'{}' is not a valid value for \
+ panic-strategy. Use 'unwind' or 'abort'.",
+ s
+ ));
+ }
+ })
+ }
+}
+
+crate::json::serde_deserialize_from_str!(PanicStrategy);
+
impl ToJson for PanicStrategy {
fn to_json(&self) -> Json {
match *self {
@@ -867,18 +921,24 @@ pub fn desc(&self) -> &str {
}
impl FromStr for SymbolVisibility {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<SymbolVisibility, ()> {
+ fn from_str(s: &str) -> Result<SymbolVisibility, Self::Err> {
match s {
"hidden" => Ok(SymbolVisibility::Hidden),
"protected" => Ok(SymbolVisibility::Protected),
"interposable" => Ok(SymbolVisibility::Interposable),
- _ => Err(()),
+ _ => Err(format!(
+ "'{}' is not a valid value for \
+ symbol-visibility. Use 'hidden', 'protected, or 'interposable'.",
+ s
+ )),
}
}
}
+crate::json::serde_deserialize_from_str!(SymbolVisibility);
+
impl ToJson for SymbolVisibility {
fn to_json(&self) -> Json {
match *self {
@@ -890,19 +950,25 @@ fn to_json(&self) -> Json {
}
impl FromStr for RelroLevel {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<RelroLevel, ()> {
+ fn from_str(s: &str) -> Result<RelroLevel, Self::Err> {
match s {
"full" => Ok(RelroLevel::Full),
"partial" => Ok(RelroLevel::Partial),
"off" => Ok(RelroLevel::Off),
"none" => Ok(RelroLevel::None),
- _ => Err(()),
+ _ => Err(format!(
+ "'{}' is not a valid value for \
+ relro-level. Use 'full', 'partial, 'off', or 'none'.",
+ s
+ )),
}
}
}
+crate::json::serde_deserialize_from_str!(RelroLevel);
+
impl ToJson for RelroLevel {
fn to_json(&self) -> Json {
match *self {
@@ -923,7 +989,7 @@ pub enum SmallDataThresholdSupport {
}
impl FromStr for SmallDataThresholdSupport {
- type Err = ();
+ type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s == "none" {
@@ -935,11 +1001,13 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
} else if let Some(arg) = s.strip_prefix("llvm-arg=") {
Ok(Self::LlvmArg(arg.to_string().into()))
} else {
- Err(())
+ Err(format!("'{s}' is not a valid value for small-data-threshold-support."))
}
}
}
+crate::json::serde_deserialize_from_str!(SmallDataThresholdSupport);
+
impl ToJson for SmallDataThresholdSupport {
fn to_json(&self) -> Value {
match self {
@@ -969,18 +1037,25 @@ pub fn desc(&self) -> &str {
}
impl FromStr for MergeFunctions {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<MergeFunctions, ()> {
+ fn from_str(s: &str) -> Result<MergeFunctions, Self::Err> {
match s {
"disabled" => Ok(MergeFunctions::Disabled),
"trampolines" => Ok(MergeFunctions::Trampolines),
"aliases" => Ok(MergeFunctions::Aliases),
- _ => Err(()),
+ _ => Err(format!(
+ "'{}' is not a valid value for \
+ merge-functions. Use 'disabled', \
+ 'trampolines', or 'aliases'.",
+ s
+ )),
}
}
}
+crate::json::serde_deserialize_from_str!(MergeFunctions);
+
impl ToJson for MergeFunctions {
fn to_json(&self) -> Json {
match *self {
@@ -1040,9 +1115,9 @@ pub const fn desc_symbol(&self) -> Symbol {
}
impl FromStr for RelocModel {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<RelocModel, ()> {
+ fn from_str(s: &str) -> Result<RelocModel, Self::Err> {
Ok(match s {
"static" => RelocModel::Static,
"pic" => RelocModel::Pic,
@@ -1051,11 +1126,19 @@ fn from_str(s: &str) -> Result<RelocModel, ()> {
"ropi" => RelocModel::Ropi,
"rwpi" => RelocModel::Rwpi,
"ropi-rwpi" => RelocModel::RopiRwpi,
- _ => return Err(()),
+ _ => {
+ return Err(format!(
+ "invalid relocation model '{s}'.
+ Run `rustc --print relocation-models` to \
+ see the list of supported values.'"
+ ));
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(RelocModel);
+
impl ToJson for RelocModel {
fn to_json(&self) -> Json {
self.desc().to_json()
@@ -1072,20 +1155,28 @@ pub enum CodeModel {
}
impl FromStr for CodeModel {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<CodeModel, ()> {
+ fn from_str(s: &str) -> Result<CodeModel, Self::Err> {
Ok(match s {
"tiny" => CodeModel::Tiny,
"small" => CodeModel::Small,
"kernel" => CodeModel::Kernel,
"medium" => CodeModel::Medium,
"large" => CodeModel::Large,
- _ => return Err(()),
+ _ => {
+ return Err(format!(
+ "'{s}' is not a valid code model. \
+ Run `rustc --print code-models` to \
+ see the list of supported values."
+ ));
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(CodeModel);
+
impl ToJson for CodeModel {
fn to_json(&self) -> Json {
match *self {
@@ -1107,17 +1198,25 @@ pub enum FloatAbi {
}
impl FromStr for FloatAbi {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<FloatAbi, ()> {
+ fn from_str(s: &str) -> Result<FloatAbi, Self::Err> {
Ok(match s {
"soft" => FloatAbi::Soft,
"hard" => FloatAbi::Hard,
- _ => return Err(()),
+ _ => {
+ return Err(format!(
+ "'{}' is not a valid value for \
+ llvm-floatabi. Use 'soft' or 'hard'.",
+ s
+ ));
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(FloatAbi);
+
impl ToJson for FloatAbi {
fn to_json(&self) -> Json {
match *self {
@@ -1138,17 +1237,24 @@ pub enum RustcAbi {
}
impl FromStr for RustcAbi {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<RustcAbi, ()> {
+ fn from_str(s: &str) -> Result<RustcAbi, Self::Err> {
Ok(match s {
"x86-sse2" => RustcAbi::X86Sse2,
"x86-softfloat" => RustcAbi::X86Softfloat,
- _ => return Err(()),
+ _ => {
+ return Err(format!(
+ "'{s}' is not a valid value for rustc-abi. \
+ Use 'x86-softfloat' or leave the field unset."
+ ));
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(RustcAbi);
+
impl ToJson for RustcAbi {
fn to_json(&self) -> Json {
match *self {
@@ -1169,9 +1275,9 @@ pub enum TlsModel {
}
impl FromStr for TlsModel {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<TlsModel, ()> {
+ fn from_str(s: &str) -> Result<TlsModel, Self::Err> {
Ok(match s {
// Note the difference "general" vs "global" difference. The model name is "general",
// but the user-facing option name is "global" for consistency with other compilers.
@@ -1180,11 +1286,19 @@ fn from_str(s: &str) -> Result<TlsModel, ()> {
"initial-exec" => TlsModel::InitialExec,
"local-exec" => TlsModel::LocalExec,
"emulated" => TlsModel::Emulated,
- _ => return Err(()),
+ _ => {
+ return Err(format!(
+ "'{s}' is not a valid TLS model. \
+ Run `rustc --print tls-models` to \
+ see the list of supported values."
+ ));
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(TlsModel);
+
impl ToJson for TlsModel {
fn to_json(&self) -> Json {
match *self {
@@ -1230,19 +1344,6 @@ fn as_str(&self) -> &'static str {
}
}
- pub(super) fn from_str(s: &str) -> Option<LinkOutputKind> {
- Some(match s {
- "dynamic-nopic-exe" => LinkOutputKind::DynamicNoPicExe,
- "dynamic-pic-exe" => LinkOutputKind::DynamicPicExe,
- "static-nopic-exe" => LinkOutputKind::StaticNoPicExe,
- "static-pic-exe" => LinkOutputKind::StaticPicExe,
- "dynamic-dylib" => LinkOutputKind::DynamicDylib,
- "static-dylib" => LinkOutputKind::StaticDylib,
- "wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
- _ => return None,
- })
- }
-
pub fn can_link_dylib(self) -> bool {
match self {
LinkOutputKind::StaticNoPicExe | LinkOutputKind::StaticPicExe => false,
@@ -1255,6 +1356,31 @@ pub fn can_link_dylib(self) -> bool {
}
}
+impl FromStr for LinkOutputKind {
+ type Err = String;
+
+ fn from_str(s: &str) -> Result<LinkOutputKind, Self::Err> {
+ Ok(match s {
+ "dynamic-nopic-exe" => LinkOutputKind::DynamicNoPicExe,
+ "dynamic-pic-exe" => LinkOutputKind::DynamicPicExe,
+ "static-nopic-exe" => LinkOutputKind::StaticNoPicExe,
+ "static-pic-exe" => LinkOutputKind::StaticPicExe,
+ "dynamic-dylib" => LinkOutputKind::DynamicDylib,
+ "static-dylib" => LinkOutputKind::StaticDylib,
+ "wasi-reactor-exe" => LinkOutputKind::WasiReactorExe,
+ _ => {
+ return Err(format!(
+ "invalid value for CRT object kind. \
+ Use '(dynamic,static)-(nopic,pic)-exe' or \
+ '(dynamic,static)-dylib' or 'wasi-reactor-exe'"
+ ));
+ }
+ })
+ }
+}
+
+crate::json::serde_deserialize_from_str!(LinkOutputKind);
+
impl fmt::Display for LinkOutputKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
@@ -1290,18 +1416,25 @@ fn as_str(&self) -> &'static str {
}
impl FromStr for DebuginfoKind {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<Self, ()> {
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"dwarf" => DebuginfoKind::Dwarf,
"dwarf-dsym" => DebuginfoKind::DwarfDsym,
"pdb" => DebuginfoKind::Pdb,
- _ => return Err(()),
+ _ => {
+ return Err(format!(
+ "'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \
+ 'dwarf-dsym' or 'pdb'."
+ ));
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(DebuginfoKind);
+
impl ToJson for DebuginfoKind {
fn to_json(&self) -> Json {
self.as_str().to_json()
@@ -1354,18 +1487,25 @@ fn as_str(&self) -> &'static str {
}
impl FromStr for SplitDebuginfo {
- type Err = ();
+ type Err = String;
- fn from_str(s: &str) -> Result<Self, ()> {
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"off" => SplitDebuginfo::Off,
"unpacked" => SplitDebuginfo::Unpacked,
"packed" => SplitDebuginfo::Packed,
- _ => return Err(()),
+ _ => {
+ return Err(format!(
+ "'{s}' is not a valid value for \
+ split-debuginfo. Use 'off', 'unpacked', or 'packed'.",
+ ));
+ }
})
}
}
+crate::json::serde_deserialize_from_str!(SplitDebuginfo);
+
impl ToJson for SplitDebuginfo {
fn to_json(&self) -> Json {
self.as_str().to_json()
@@ -1378,7 +1518,9 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq, serde_derive::Deserialize)]
+#[serde(tag = "kind")]
+#[serde(rename_all = "kebab-case")]
pub enum StackProbeType {
/// Don't emit any stack probes.
None,
@@ -1390,44 +1532,10 @@ pub enum StackProbeType {
Call,
/// Use inline option for LLVM versions later than specified in `min_llvm_version_for_inline`
/// and call `__rust_probestack` otherwise.
- InlineOrCall { min_llvm_version_for_inline: (u32, u32, u32) },
-}
-
-impl StackProbeType {
- fn from_json(json: &Json) -> Result<Self, String> {
- let object = json.as_object().ok_or_else(|| "expected a JSON object")?;
- let kind = object
- .get("kind")
- .and_then(|o| o.as_str())
- .ok_or_else(|| "expected `kind` to be a string")?;
- match kind {
- "none" => Ok(StackProbeType::None),
- "inline" => Ok(StackProbeType::Inline),
- "call" => Ok(StackProbeType::Call),
- "inline-or-call" => {
- let min_version = object
- .get("min-llvm-version-for-inline")
- .and_then(|o| o.as_array())
- .ok_or_else(|| "expected `min-llvm-version-for-inline` to be an array")?;
- let mut iter = min_version.into_iter().map(|v| {
- let int = v.as_u64().ok_or_else(
- || "expected `min-llvm-version-for-inline` values to be integers",
- )?;
- u32::try_from(int)
- .map_err(|_| "`min-llvm-version-for-inline` values don't convert to u32")
- });
- let min_llvm_version_for_inline = (
- iter.next().unwrap_or(Ok(11))?,
- iter.next().unwrap_or(Ok(0))?,
- iter.next().unwrap_or(Ok(0))?,
- );
- Ok(StackProbeType::InlineOrCall { min_llvm_version_for_inline })
- }
- _ => Err(String::from(
- "`kind` expected to be one of `none`, `inline`, `call` or `inline-or-call`",
- )),
- }
- }
+ InlineOrCall {
+ #[serde(rename = "min-llvm-version-for-inline")]
+ min_llvm_version_for_inline: (u32, u32, u32),
+ },
}
impl ToJson for StackProbeType {
@@ -1549,6 +1657,29 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
+impl FromStr for SanitizerSet {
+ type Err = String;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "address" => SanitizerSet::ADDRESS,
+ "cfi" => SanitizerSet::CFI,
+ "dataflow" => SanitizerSet::DATAFLOW,
+ "kcfi" => SanitizerSet::KCFI,
+ "kernel-address" => SanitizerSet::KERNELADDRESS,
+ "leak" => SanitizerSet::LEAK,
+ "memory" => SanitizerSet::MEMORY,
+ "memtag" => SanitizerSet::MEMTAG,
+ "safestack" => SanitizerSet::SAFESTACK,
+ "shadow-call-stack" => SanitizerSet::SHADOWCALLSTACK,
+ "thread" => SanitizerSet::THREAD,
+ "hwaddress" => SanitizerSet::HWADDRESS,
+ s => return Err(format!("unknown sanitizer {s}")),
+ })
+ }
+}
+
+crate::json::serde_deserialize_from_str!(SanitizerSet);
+
impl ToJson for SanitizerSet {
fn to_json(&self) -> Json {
self.into_iter()
@@ -1587,17 +1718,19 @@ pub fn ratchet(&mut self, rhs: FramePointer) -> FramePointer {
}
impl FromStr for FramePointer {
- type Err = ();
- fn from_str(s: &str) -> Result<Self, ()> {
+ type Err = String;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"always" => Self::Always,
"non-leaf" => Self::NonLeaf,
"may-omit" => Self::MayOmit,
- _ => return Err(()),
+ _ => return Err(format!("'{s}' is not a valid value for frame-pointer")),
})
}
}
+crate::json::serde_deserialize_from_str!(FramePointer);
+
impl ToJson for FramePointer {
fn to_json(&self) -> Json {
match *self {
@@ -1685,7 +1818,7 @@ pub fn to_object(&self) -> object::BinaryFormat {
}
impl FromStr for BinaryFormat {
- type Err = ();
+ type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"coff" => Ok(Self::Coff),
@@ -1693,11 +1826,16 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
"mach-o" => Ok(Self::MachO),
"wasm" => Ok(Self::Wasm),
"xcoff" => Ok(Self::Xcoff),
- _ => Err(()),
+ _ => Err(format!(
+ "'{s}' is not a valid value for binary_format. \
+ Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' "
+ )),
}
}
}
+crate::json::serde_deserialize_from_str!(BinaryFormat);
+
impl ToJson for BinaryFormat {
fn to_json(&self) -> Json {
match self {
@@ -2130,12 +2268,11 @@ macro_rules! cvs {
#[derive(Debug, PartialEq)]
pub struct TargetWarnings {
unused_fields: Vec<String>,
- incorrect_type: Vec<String>,
}
impl TargetWarnings {
pub fn empty() -> Self {
- Self { unused_fields: Vec::new(), incorrect_type: Vec::new() }
+ Self { unused_fields: Vec::new() }
}
pub fn warning_messages(&self) -> Vec<String> {
@@ -2146,12 +2283,6 @@ pub fn warning_messages(&self) -> Vec<String> {
self.unused_fields.join(", ")
));
}
- if !self.incorrect_type.is_empty() {
- warnings.push(format!(
- "target json file contains fields whose value doesn't have the correct json type: {}",
- self.incorrect_type.join(", ")
- ));
- }
warnings
}
}
@@ -3325,7 +3456,8 @@ macro_rules! check_matches {
/// Test target self-consistency and JSON encoding/decoding roundtrip.
#[cfg(test)]
fn test_target(mut self) {
- let recycled_target = Target::from_json(self.to_json()).map(|(j, _)| j);
+ let recycled_target =
+ Target::from_json(&serde_json::to_string(&self.to_json()).unwrap()).map(|(j, _)| j);
self.update_to_cli();
self.check_consistency(TargetKind::Builtin).unwrap();
assert_eq!(recycled_target, Ok(self));
@@ -3373,8 +3505,7 @@ pub fn search(
fn load_file(path: &Path) -> Result<(Target, TargetWarnings), String> {
let contents = fs::read_to_string(path).map_err(|e| e.to_string())?;
- let obj = serde_json::from_str(&contents).map_err(|e| e.to_string())?;
- Target::from_json(obj)
+ Target::from_json(&contents)
}
match *target_tuple {
@@ -3422,10 +3553,7 @@ fn load_file(path: &Path) -> Result<(Target, TargetWarnings), String> {
Err(format!("could not find specification for target {target_tuple:?}"))
}
}
- TargetTuple::TargetJson { ref contents, .. } => {
- let obj = serde_json::from_str(contents).map_err(|e| e.to_string())?;
- Target::from_json(obj)
- }
+ TargetTuple::TargetJson { ref contents, .. } => Target::from_json(contents),
}
}
diff --git a/compiler/rustc_target/src/tests.rs b/compiler/rustc_target/src/tests.rs
index 7637517..ee847a8 100644
--- a/compiler/rustc_target/src/tests.rs
+++ b/compiler/rustc_target/src/tests.rs
@@ -2,8 +2,7 @@
#[test]
fn report_unused_fields() {
- let json = serde_json::from_str(
- r#"
+ let json = r#"
{
"arch": "powerpc64",
"data-layout": "e-m:e-i64:64-n32:64",
@@ -11,47 +10,8 @@ fn report_unused_fields() {
"target-pointer-width": "64",
"code-mode": "foo"
}
- "#,
- )
- .unwrap();
- let warnings = Target::from_json(json).unwrap().1;
- assert_eq!(warnings.warning_messages().len(), 1);
- assert!(warnings.warning_messages().join("\n").contains("code-mode"));
-}
-
-#[test]
-fn report_incorrect_json_type() {
- let json = serde_json::from_str(
- r#"
- {
- "arch": "powerpc64",
- "data-layout": "e-m:e-i64:64-n32:64",
- "llvm-target": "powerpc64le-elf",
- "target-pointer-width": "64",
- "link-env-remove": "foo"
- }
- "#,
- )
- .unwrap();
- let warnings = Target::from_json(json).unwrap().1;
- assert_eq!(warnings.warning_messages().len(), 1);
- assert!(warnings.warning_messages().join("\n").contains("link-env-remove"));
-}
-
-#[test]
-fn no_warnings_for_valid_target() {
- let json = serde_json::from_str(
- r#"
- {
- "arch": "powerpc64",
- "data-layout": "e-m:e-i64:64-n32:64",
- "llvm-target": "powerpc64le-elf",
- "target-pointer-width": "64",
- "link-env-remove": ["foo"]
- }
- "#,
- )
- .unwrap();
- let warnings = Target::from_json(json).unwrap().1;
- assert_eq!(warnings.warning_messages().len(), 0);
+ "#;
+ let result = Target::from_json(json);
+ eprintln!("{result:#?}");
+ assert!(result.is_err());
}
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 163e2b3..79f7e22 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -603,12 +603,6 @@ fn layout_of_uncached<'tcx>(
.flatten()
};
- let dont_niche_optimize_enum = def.repr().inhibit_enum_layout_opt()
- || def
- .variants()
- .iter_enumerated()
- .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()));
-
let maybe_unsized = def.is_struct()
&& def.non_enum_variant().tail_opt().is_some_and(|last_field| {
let typing_env = ty::TypingEnv::post_analysis(tcx, def.did());
@@ -625,7 +619,6 @@ fn layout_of_uncached<'tcx>(
tcx.layout_scalar_valid_range(def.did()),
get_discriminant_type,
discriminants_iter(),
- dont_niche_optimize_enum,
!maybe_unsized,
)
.map_err(|err| map_error(cx, ty, err))?;
@@ -651,7 +644,6 @@ fn layout_of_uncached<'tcx>(
tcx.layout_scalar_valid_range(def.did()),
get_discriminant_type,
discriminants_iter(),
- dont_niche_optimize_enum,
!maybe_unsized,
) else {
bug!("failed to compute unsized layout of {ty:?}");
diff --git a/library/Cargo.lock b/library/Cargo.lock
index 94155e0..c23c234 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -90,11 +90,10 @@
[[package]]
name = "fortanix-sgx-abi"
-version = "0.5.0"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57cafc2274c10fab234f176b25903ce17e690fca7597090d50880e047a0389c5"
+checksum = "5efc85edd5b83e8394f4371dd0da6859dff63dd387dab8568fece6af4cde6f84"
dependencies = [
- "compiler_builtins",
"rustc-std-workspace-core",
]
diff --git a/library/core/src/borrow.rs b/library/core/src/borrow.rs
index ccb1cc4..da05f236 100644
--- a/library/core/src/borrow.rs
+++ b/library/core/src/borrow.rs
@@ -223,20 +223,20 @@ fn borrow_mut(&mut self) -> &mut T {
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for &T {
fn borrow(&self) -> &T {
- &**self
+ self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for &mut T {
fn borrow(&self) -> &T {
- &**self
+ self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> BorrowMut<T> for &mut T {
fn borrow_mut(&mut self) -> &mut T {
- &mut **self
+ self
}
}
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index a34d1b4..51d037d 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -590,7 +590,7 @@ impl<T: PointeeSized> Clone for &T {
#[inline(always)]
#[rustc_diagnostic_item = "noop_method_clone"]
fn clone(&self) -> Self {
- *self
+ self
}
}
diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs
index 06ab15d..17d3eef 100644
--- a/library/core/src/iter/adapters/rev.rs
+++ b/library/core/src/iter/adapters/rev.rs
@@ -20,6 +20,25 @@ impl<T> Rev<T> {
pub(in crate::iter) fn new(iter: T) -> Rev<T> {
Rev { iter }
}
+
+ /// Consumes the `Rev`, returning the inner iterator.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// #![feature(rev_into_inner)]
+ ///
+ /// let s = "foobar";
+ /// let mut rev = s.chars().rev();
+ /// assert_eq!(rev.next(), Some('r'));
+ /// assert_eq!(rev.next(), Some('a'));
+ /// assert_eq!(rev.next(), Some('b'));
+ /// assert_eq!(rev.into_inner().collect::<String>(), "foo");
+ /// ```
+ #[unstable(feature = "rev_into_inner", issue = "144277")]
+ pub fn into_inner(self) -> T {
+ self.iter
+ }
}
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 2198d09..3340763 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -960,7 +960,7 @@ pub fn drop<T>(_x: T) {}
///
/// This function is not magic; it is literally defined as
/// ```
-/// pub fn copy<T: Copy>(x: &T) -> T { *x }
+/// pub const fn copy<T: Copy>(x: &T) -> T { *x }
/// ```
///
/// It is useful when you want to pass a function pointer to a combinator, rather than defining a new closure.
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index 9d9d180..c2dede9 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -158,7 +158,7 @@ impl<T: ?Sized> const Deref for &T {
#[rustc_diagnostic_item = "noop_method_deref"]
fn deref(&self) -> &T {
- *self
+ self
}
}
@@ -171,7 +171,7 @@ impl<T: ?Sized> const Deref for &mut T {
type Target = T;
fn deref(&self) -> &T {
- *self
+ self
}
}
@@ -280,7 +280,7 @@ pub trait DerefMut: ~const Deref + PointeeSized {
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
impl<T: ?Sized> const DerefMut for &mut T {
fn deref_mut(&mut self) -> &mut T {
- *self
+ self
}
}
diff --git a/library/core/src/slice/sort/select.rs b/library/core/src/slice/sort/select.rs
index 82194db..fc31013 100644
--- a/library/core/src/slice/sort/select.rs
+++ b/library/core/src/slice/sort/select.rs
@@ -101,8 +101,7 @@ fn partition_at_index_loop<'a, T, F>(
// slice. Partition the slice into elements equal to and elements greater than the pivot.
// This case is usually hit when the slice contains many duplicate elements.
if let Some(p) = ancestor_pivot {
- // SAFETY: choose_pivot promises to return a valid pivot position.
- let pivot = unsafe { v.get_unchecked(pivot_pos) };
+ let pivot = &v[pivot_pos];
if !is_less(p, pivot) {
let num_lt = partition(v, pivot_pos, &mut |a, b| !is_less(b, a));
diff --git a/library/core/src/slice/sort/shared/pivot.rs b/library/core/src/slice/sort/shared/pivot.rs
index 3aace48..9eb60f8 100644
--- a/library/core/src/slice/sort/shared/pivot.rs
+++ b/library/core/src/slice/sort/shared/pivot.rs
@@ -1,6 +1,6 @@
//! This module contains the logic for pivot selection.
-use crate::intrinsics;
+use crate::{hint, intrinsics};
// Recursively select a pseudomedian if above this threshold.
const PSEUDO_MEDIAN_REC_THRESHOLD: usize = 64;
@@ -9,6 +9,7 @@
///
/// This chooses a pivot by sampling an adaptive amount of points, approximating
/// the quality of a median of sqrt(n) elements.
+#[inline]
pub fn choose_pivot<T, F: FnMut(&T, &T) -> bool>(v: &[T], is_less: &mut F) -> usize {
// We use unsafe code and raw pointers here because we're dealing with
// heavy recursion. Passing safe slices around would involve a lot of
@@ -22,7 +23,7 @@ pub fn choose_pivot<T, F: FnMut(&T, &T) -> bool>(v: &[T], is_less: &mut F) -> us
// SAFETY: a, b, c point to initialized regions of len_div_8 elements,
// satisfying median3 and median3_rec's preconditions as v_base points
// to an initialized region of n = len elements.
- unsafe {
+ let index = unsafe {
let v_base = v.as_ptr();
let len_div_8 = len / 8;
@@ -35,6 +36,11 @@ pub fn choose_pivot<T, F: FnMut(&T, &T) -> bool>(v: &[T], is_less: &mut F) -> us
} else {
median3_rec(a, b, c, len_div_8, is_less).offset_from_unsigned(v_base)
}
+ };
+ // SAFETY: preconditions must have been met for offset_from_unsigned()
+ unsafe {
+ hint::assert_unchecked(index < v.len());
+ index
}
}
diff --git a/library/core/src/slice/sort/stable/quicksort.rs b/library/core/src/slice/sort/stable/quicksort.rs
index 3c96887..0439ba8 100644
--- a/library/core/src/slice/sort/stable/quicksort.rs
+++ b/library/core/src/slice/sort/stable/quicksort.rs
@@ -37,10 +37,6 @@ pub fn quicksort<T, F: FnMut(&T, &T) -> bool>(
limit -= 1;
let pivot_pos = choose_pivot(v, is_less);
- // SAFETY: choose_pivot promises to return a valid pivot index.
- unsafe {
- intrinsics::assume(pivot_pos < v.len());
- }
// SAFETY: We only access the temporary copy for Freeze types, otherwise
// self-modifications via `is_less` would not be observed and this would
diff --git a/library/core/src/slice/sort/unstable/quicksort.rs b/library/core/src/slice/sort/unstable/quicksort.rs
index 98efee2..bdf56a8 100644
--- a/library/core/src/slice/sort/unstable/quicksort.rs
+++ b/library/core/src/slice/sort/unstable/quicksort.rs
@@ -48,8 +48,7 @@ pub(crate) fn quicksort<'a, T, F>(
// slice. Partition the slice into elements equal to and elements greater than the pivot.
// This case is usually hit when the slice contains many duplicate elements.
if let Some(p) = ancestor_pivot {
- // SAFETY: We assume choose_pivot yields an in-bounds position.
- if !is_less(p, unsafe { v.get_unchecked(pivot_pos) }) {
+ if !is_less(p, &v[pivot_pos]) {
let num_lt = partition(v, pivot_pos, &mut |a, b| !is_less(b, a));
// Continue sorting elements greater than the pivot. We know that `num_lt` contains
diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs
index 193d588..8bf4094 100644
--- a/library/coretests/tests/num/dec2flt/float.rs
+++ b/library/coretests/tests/num/dec2flt/float.rs
@@ -1,13 +1,14 @@
use core::num::dec2flt::float::RawFloat;
+use crate::num::{ldexp_f32, ldexp_f64};
+
// FIXME(f16_f128): enable on all targets once possible.
#[test]
#[cfg(target_has_reliable_f16)]
fn test_f16_integer_decode() {
assert_eq!(3.14159265359f16.integer_decode(), (1608, -9, 1));
assert_eq!((-8573.5918555f16).integer_decode(), (1072, 3, -1));
- #[cfg(not(miri))] // miri doesn't have powf16
- assert_eq!(2f16.powf(14.0).integer_decode(), (1 << 10, 4, 1));
+ assert_eq!(crate::num::ldexp_f16(1.0, 14).integer_decode(), (1 << 10, 4, 1));
assert_eq!(0f16.integer_decode(), (0, -25, 1));
assert_eq!((-0f16).integer_decode(), (0, -25, -1));
assert_eq!(f16::INFINITY.integer_decode(), (1 << 10, 6, 1));
@@ -23,8 +24,7 @@ fn test_f16_integer_decode() {
fn test_f32_integer_decode() {
assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
- // Set 2^100 directly instead of using powf, because it doesn't guarantee precision
- assert_eq!(1.2676506e30_f32.integer_decode(), (8388608, 77, 1));
+ assert_eq!(ldexp_f32(1.0, 100).integer_decode(), (8388608, 77, 1));
assert_eq!(0f32.integer_decode(), (0, -150, 1));
assert_eq!((-0f32).integer_decode(), (0, -150, -1));
assert_eq!(f32::INFINITY.integer_decode(), (8388608, 105, 1));
@@ -40,8 +40,7 @@ fn test_f32_integer_decode() {
fn test_f64_integer_decode() {
assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
- // Set 2^100 directly instead of using powf, because it doesn't guarantee precision
- assert_eq!(1.2676506002282294e30_f64.integer_decode(), (4503599627370496, 48, 1));
+ assert_eq!(ldexp_f64(1.0, 100).integer_decode(), (4503599627370496, 48, 1));
assert_eq!(0f64.integer_decode(), (0, -1075, 1));
assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
assert_eq!(f64::INFINITY.integer_decode(), (4503599627370496, 972, 1));
diff --git a/library/coretests/tests/num/flt2dec/estimator.rs b/library/coretests/tests/num/flt2dec/estimator.rs
index da203b5..f532826 100644
--- a/library/coretests/tests/num/flt2dec/estimator.rs
+++ b/library/coretests/tests/num/flt2dec/estimator.rs
@@ -1,5 +1,7 @@
use core::num::flt2dec::estimator::*;
+use crate::num::ldexp_f64;
+
#[test]
fn test_estimate_scaling_factor() {
macro_rules! assert_almost_eq {
@@ -56,7 +58,7 @@ macro_rules! assert_almost_eq {
let step = if cfg!(miri) { 37 } else { 1 };
for i in (-1074..972).step_by(step) {
- let expected = super::ldexp_f64(1.0, i).log10().ceil();
+ let expected = ldexp_f64(1.0, i).log10().ceil();
assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
}
}
diff --git a/library/coretests/tests/num/flt2dec/mod.rs b/library/coretests/tests/num/flt2dec/mod.rs
index ce36db3..4e73bd1 100644
--- a/library/coretests/tests/num/flt2dec/mod.rs
+++ b/library/coretests/tests/num/flt2dec/mod.rs
@@ -6,6 +6,8 @@
use std::mem::MaybeUninit;
use std::{fmt, str};
+use crate::num::{ldexp_f32, ldexp_f64};
+
mod estimator;
mod strategy {
mod dragon;
@@ -75,24 +77,6 @@ macro_rules! try_fixed {
})
}
-#[cfg(target_has_reliable_f16)]
-fn ldexp_f16(a: f16, b: i32) -> f16 {
- ldexp_f64(a as f64, b) as f16
-}
-
-fn ldexp_f32(a: f32, b: i32) -> f32 {
- ldexp_f64(a as f64, b) as f32
-}
-
-fn ldexp_f64(a: f64, b: i32) -> f64 {
- unsafe extern "C" {
- fn ldexp(x: f64, n: i32) -> f64;
- }
- // SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
- // cause undefined behavior
- unsafe { ldexp(a, b) }
-}
-
fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16)
where
T: DecodableFloat,
@@ -268,7 +252,7 @@ pub fn f16_shortest_sanity_test<F>(mut f: F)
// 10^2 * 0.31984375
// 10^2 * 0.32
// 10^2 * 0.3203125
- check_shortest!(f(ldexp_f16(1.0, 5)) => b"32", 2);
+ check_shortest!(f(crate::num::ldexp_f16(1.0, 5)) => b"32", 2);
// 10^5 * 0.65472
// 10^5 * 0.65504
@@ -283,7 +267,7 @@ pub fn f16_shortest_sanity_test<F>(mut f: F)
// 10^-9 * 0
// 10^-9 * 0.59604644775390625
// 10^-8 * 0.11920928955078125
- let minf16 = ldexp_f16(1.0, -24);
+ let minf16 = crate::num::ldexp_f16(1.0, -24);
check_shortest!(f(minf16) => b"6", -7);
}
@@ -292,7 +276,7 @@ pub fn f16_exact_sanity_test<F>(mut f: F)
where
F: for<'a> FnMut(&Decoded, &'a mut [MaybeUninit<u8>], i16) -> (&'a [u8], i16),
{
- let minf16 = ldexp_f16(1.0, -24);
+ let minf16 = crate::num::ldexp_f16(1.0, -24);
check_exact!(f(0.1f16) => b"999755859375 ", -1);
check_exact!(f(0.5f16) => b"5 ", 0);
@@ -642,7 +626,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
assert_eq!(to_string(f, f16::MAX, Minus, 1), "65500.0");
assert_eq!(to_string(f, f16::MAX, Minus, 8), "65500.00000000");
- let minf16 = ldexp_f16(1.0, -24);
+ let minf16 = crate::num::ldexp_f16(1.0, -24);
assert_eq!(to_string(f, minf16, Minus, 0), "0.00000006");
assert_eq!(to_string(f, minf16, Minus, 8), "0.00000006");
assert_eq!(to_string(f, minf16, Minus, 9), "0.000000060");
@@ -766,7 +750,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: b
assert_eq!(to_string(f, f16::MAX, Minus, (-4, 4), false), "6.55e4");
assert_eq!(to_string(f, f16::MAX, Minus, (-5, 5), false), "65500");
- let minf16 = ldexp_f16(1.0, -24);
+ let minf16 = crate::num::ldexp_f16(1.0, -24);
assert_eq!(to_string(f, minf16, Minus, (-2, 2), false), "6e-8");
assert_eq!(to_string(f, minf16, Minus, (-7, 7), false), "6e-8");
assert_eq!(to_string(f, minf16, Minus, (-8, 8), false), "0.00000006");
@@ -922,7 +906,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) ->
assert_eq!(to_string(f, f16::MAX, Minus, 6, false), "6.55040e4");
assert_eq!(to_string(f, f16::MAX, Minus, 16, false), "6.550400000000000e4");
- let minf16 = ldexp_f16(1.0, -24);
+ let minf16 = crate::num::ldexp_f16(1.0, -24);
assert_eq!(to_string(f, minf16, Minus, 1, false), "6e-8");
assert_eq!(to_string(f, minf16, Minus, 2, false), "6.0e-8");
assert_eq!(to_string(f, minf16, Minus, 4, false), "5.960e-8");
@@ -1229,7 +1213,7 @@ fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize) -> String
#[cfg(target_has_reliable_f16)]
{
- let minf16 = ldexp_f16(1.0, -24);
+ let minf16 = crate::num::ldexp_f16(1.0, -24);
assert_eq!(to_string(f, minf16, Minus, 0), "0");
assert_eq!(to_string(f, minf16, Minus, 1), "0.0");
assert_eq!(to_string(f, minf16, Minus, 2), "0.00");
diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs
index f340926..54e54f7 100644
--- a/library/coretests/tests/num/mod.rs
+++ b/library/coretests/tests/num/mod.rs
@@ -54,6 +54,27 @@ macro_rules! assume_usize_width {
}
}
+/// Return `a * 2^b`.
+#[cfg(target_has_reliable_f16)]
+fn ldexp_f16(a: f16, b: i32) -> f16 {
+ ldexp_f64(a as f64, b) as f16
+}
+
+/// Return `a * 2^b`.
+fn ldexp_f32(a: f32, b: i32) -> f32 {
+ ldexp_f64(a as f64, b) as f32
+}
+
+/// Return `a * 2^b`.
+fn ldexp_f64(a: f64, b: i32) -> f64 {
+ unsafe extern "C" {
+ fn ldexp(x: f64, n: i32) -> f64;
+ }
+ // SAFETY: assuming a correct `ldexp` has been supplied, the given arguments cannot possibly
+ // cause undefined behavior
+ unsafe { ldexp(a, b) }
+}
+
/// Helper function for testing numeric operations
pub fn test_num<T>(ten: T, two: T)
where
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index ba1e1f5..6e23c01 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -66,7 +66,7 @@
dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] }
[target.x86_64-fortanix-unknown-sgx.dependencies]
-fortanix-sgx-abi = { version = "0.5.0", features = [
+fortanix-sgx-abi = { version = "0.6.1", features = [
'rustc-dep-of-std',
], public = true }
diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs
index 884cbd4..16e3487 100644
--- a/library/std/src/sys/net/connection/uefi/mod.rs
+++ b/library/std/src/sys/net/connection/uefi/mod.rs
@@ -86,11 +86,11 @@ pub fn is_write_vectored(&self) -> bool {
}
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
- unsupported()
+ self.inner.peer_addr()
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- unsupported()
+ self.inner.socket_addr()
}
pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
@@ -114,7 +114,7 @@ pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
}
pub fn nodelay(&self) -> io::Result<bool> {
- unsupported()
+ self.inner.nodelay()
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
@@ -122,7 +122,7 @@ pub fn set_ttl(&self, _: u32) -> io::Result<()> {
}
pub fn ttl(&self) -> io::Result<u32> {
- unsupported()
+ self.inner.ttl()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
@@ -140,7 +140,9 @@ fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
-pub struct TcpListener(!);
+pub struct TcpListener {
+ inner: tcp::Tcp,
+}
impl TcpListener {
pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
@@ -148,45 +150,45 @@ pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
}
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
- self.0
+ unsupported()
}
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
- self.0
+ unsupported()
}
pub fn duplicate(&self) -> io::Result<TcpListener> {
- self.0
+ unsupported()
}
pub fn set_ttl(&self, _: u32) -> io::Result<()> {
- self.0
+ unsupported()
}
pub fn ttl(&self) -> io::Result<u32> {
- self.0
+ self.inner.ttl()
}
pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
- self.0
+ unsupported()
}
pub fn only_v6(&self) -> io::Result<bool> {
- self.0
+ unsupported()
}
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- self.0
+ unsupported()
}
pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
- self.0
+ unsupported()
}
}
impl fmt::Debug for TcpListener {
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
- self.0
+ todo!()
}
}
diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs
index 1152f69..aac9700 100644
--- a/library/std/src/sys/net/connection/uefi/tcp.rs
+++ b/library/std/src/sys/net/connection/uefi/tcp.rs
@@ -1,6 +1,8 @@
use super::tcp4;
use crate::io;
use crate::net::SocketAddr;
+use crate::ptr::NonNull;
+use crate::sys::{helpers, unsupported};
use crate::time::Duration;
pub(crate) enum Tcp {
@@ -31,4 +33,44 @@ pub(crate) fn read(&self, buf: &mut [u8], timeout: Option<Duration>) -> io::Resu
Self::V4(client) => client.read(buf, timeout),
}
}
+
+ pub(crate) fn ttl(&self) -> io::Result<u32> {
+ match self {
+ Self::V4(client) => client.get_mode_data().map(|x| x.time_to_live.into()),
+ }
+ }
+
+ pub(crate) fn nodelay(&self) -> io::Result<bool> {
+ match self {
+ Self::V4(client) => {
+ let temp = client.get_mode_data()?;
+ match NonNull::new(temp.control_option) {
+ Some(x) => unsafe { Ok(x.as_ref().enable_nagle.into()) },
+ None => unsupported(),
+ }
+ }
+ }
+ }
+
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ match self {
+ Self::V4(client) => client.get_mode_data().map(|x| {
+ SocketAddr::new(
+ helpers::ipv4_from_r_efi(x.access_point.remote_address).into(),
+ x.access_point.remote_port,
+ )
+ }),
+ }
+ }
+
+ pub fn socket_addr(&self) -> io::Result<SocketAddr> {
+ match self {
+ Self::V4(client) => client.get_mode_data().map(|x| {
+ SocketAddr::new(
+ helpers::ipv4_from_r_efi(x.access_point.station_address).into(),
+ x.access_point.station_port,
+ )
+ }),
+ }
+ }
}
diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs
index 6342718..75862ff 100644
--- a/library/std/src/sys/net/connection/uefi/tcp4.rs
+++ b/library/std/src/sys/net/connection/uefi/tcp4.rs
@@ -67,6 +67,24 @@ pub(crate) fn configure(
if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
}
+ pub(crate) fn get_mode_data(&self) -> io::Result<tcp4::ConfigData> {
+ let mut config_data = tcp4::ConfigData::default();
+ let protocol = self.protocol.as_ptr();
+
+ let r = unsafe {
+ ((*protocol).get_mode_data)(
+ protocol,
+ crate::ptr::null_mut(),
+ &mut config_data,
+ crate::ptr::null_mut(),
+ crate::ptr::null_mut(),
+ crate::ptr::null_mut(),
+ )
+ };
+
+ if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(config_data) }
+ }
+
pub(crate) fn connect(&self, timeout: Option<Duration>) -> io::Result<()> {
let evt = unsafe { self.create_evt() }?;
let completion_token =
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
index dea4412..5041770 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs
@@ -267,7 +267,7 @@ pub fn send(event_set: u64, tcs: Option<Tcs>) -> IoResult<()> {
/// Usercall `insecure_time`. See the ABI documentation for more information.
#[unstable(feature = "sgx_platform", issue = "56975")]
pub fn insecure_time() -> Duration {
- let t = unsafe { raw::insecure_time() };
+ let t = unsafe { raw::insecure_time().0 };
Duration::new(t / 1_000_000_000, (t % 1_000_000_000) as _)
}
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index 4204816..271dc4d 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -761,3 +761,7 @@ fn drop(&mut self) {
pub(crate) const fn ipv4_to_r_efi(addr: crate::net::Ipv4Addr) -> efi::Ipv4Address {
efi::Ipv4Address { addr: addr.octets() }
}
+
+pub(crate) const fn ipv4_from_r_efi(ip: efi::Ipv4Address) -> crate::net::Ipv4Addr {
+ crate::net::Ipv4Addr::new(ip.addr[0], ip.addr[1], ip.addr[2], ip.addr[3])
+}
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index a0371eb..b119f2d 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -19,6 +19,7 @@
"too_many_arguments",
"needless_lifetimes", // people want to keep the lifetimes
"wrong_self_convention",
+ "approx_constant", // libcore is what defines those
];
fn lint_args(builder: &Builder<'_>, config: &LintConfig, ignored_rules: &[&str]) -> Vec<String> {
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index d346062..ebbb569 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1113,6 +1113,12 @@ fn run(self, builder: &Builder<'_>) {
8 * std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32
});
cmd.arg(jobs.to_string());
+ // pass the path to the npm command used for installing js deps.
+ if let Some(npm) = &builder.config.npm {
+ cmd.arg(npm);
+ } else {
+ cmd.arg("npm");
+ }
if builder.is_verbose() {
cmd.arg("--verbose");
}
diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md
index 9bfc60e..b1feef9 100644
--- a/src/doc/rustc-dev-guide/src/tests/ui.md
+++ b/src/doc/rustc-dev-guide/src/tests/ui.md
@@ -309,7 +309,8 @@
Use `//~?` to match an error without line information.
`//~?` is precise and will not match errors if their line information is available.
-It should be preferred to using `error-pattern`, which is imprecise and non-exhaustive.
+For tests wishing to match against compiler diagnostics, error annotations should
+be preferred over //@ error-pattern, //@ error-pattern is imprecise and non-exhaustive.
```rust,ignore
//@ compile-flags: --print yyyy
@@ -347,8 +348,6 @@
}
```
-Use of `error-pattern` is not recommended in general.
-
For strict testing of compile time output, try to use the line annotations `//~` as much as
possible, including `//~?` annotations for diagnostics without spans.
@@ -359,7 +358,8 @@
For checking runtime output, `//@ check-run-results` may be preferable.
-Only use `error-pattern` if none of the above works.
+Only use `error-pattern` if none of the above works, such as when finding a
+specific string pattern in a runtime panic output.
Line annotations `//~` and `error-pattern` are compatible and can be used in the same test.
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 38ba6b4..a32c2f7 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -444,7 +444,7 @@ fn add_exe_suffix(input: String, target: &TargetTuple) -> String {
let exe_suffix = match target {
TargetTuple::TargetTuple(_) => Target::expect_builtin(target).options.exe_suffix,
TargetTuple::TargetJson { contents, .. } => {
- Target::from_json(contents.parse().unwrap()).unwrap().0.options.exe_suffix
+ Target::from_json(contents).unwrap().0.options.exe_suffix
}
};
input + &exe_suffix
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index 3c9be29..e2f86b8 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -100,9 +100,22 @@ pub(crate) fn build_index(
let crate_doc =
short_markdown_summary(&krate.module.doc_value(), &krate.module.link_names(cache));
+ #[derive(Eq, Ord, PartialEq, PartialOrd)]
+ struct SerSymbolAsStr(Symbol);
+
+ impl Serialize for SerSymbolAsStr {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.as_str().serialize(serializer)
+ }
+ }
+
+ type AliasMap = BTreeMap<SerSymbolAsStr, Vec<usize>>;
// Aliases added through `#[doc(alias = "...")]`. Since a few items can have the same alias,
// we need the alias element to have an array of items.
- let mut aliases: BTreeMap<String, Vec<usize>> = BTreeMap::new();
+ let mut aliases: AliasMap = BTreeMap::new();
// Sort search index items. This improves the compressibility of the search index.
cache.search_index.sort_unstable_by(|k1, k2| {
@@ -116,7 +129,7 @@ pub(crate) fn build_index(
// Set up alias indexes.
for (i, item) in cache.search_index.iter().enumerate() {
for alias in &item.aliases[..] {
- aliases.entry(alias.to_string()).or_default().push(i);
+ aliases.entry(SerSymbolAsStr(*alias)).or_default().push(i);
}
}
@@ -474,7 +487,7 @@ struct CrateData<'a> {
// The String is alias name and the vec is the list of the elements with this alias.
//
// To be noted: the `usize` elements are indexes to `items`.
- aliases: &'a BTreeMap<String, Vec<usize>>,
+ aliases: &'a AliasMap,
// Used when a type has more than one impl with an associated item with the same name.
associated_item_disambiguators: &'a Vec<(usize, String)>,
// A list of shard lengths encoded as vlqhex. See the comment in write_vlqhex_to_string
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 3c4af0d..8e3d07b 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -568,7 +568,11 @@
break;
case "-":
ev.preventDefault();
- collapseAllDocs();
+ collapseAllDocs(false);
+ break;
+ case "_":
+ ev.preventDefault();
+ collapseAllDocs(true);
break;
case "?":
@@ -1038,11 +1042,14 @@
innerToggle.children[0].innerText = "Summary";
}
- function collapseAllDocs() {
+ /**
+ * @param {boolean} collapseImpls - also collapse impl blocks if set to true
+ */
+ function collapseAllDocs(collapseImpls) {
const innerToggle = document.getElementById(toggleAllDocsId);
addClass(innerToggle, "will-expand");
onEachLazy(document.getElementsByClassName("toggle"), e => {
- if (e.parentNode.id !== "implementations-list" ||
+ if ((collapseImpls || e.parentNode.id !== "implementations-list") ||
(!hasClass(e, "implementors-toggle") &&
!hasClass(e, "type-contents-toggle"))
) {
@@ -1053,7 +1060,10 @@
innerToggle.children[0].innerText = "Show all";
}
- function toggleAllDocs() {
+ /**
+ * @param {MouseEvent=} ev
+ */
+ function toggleAllDocs(ev) {
const innerToggle = document.getElementById(toggleAllDocsId);
if (!innerToggle) {
return;
@@ -1061,7 +1071,7 @@
if (hasClass(innerToggle, "will-expand")) {
expandAllDocs();
} else {
- collapseAllDocs();
+ collapseAllDocs(ev !== undefined && ev.shiftKey);
}
}
@@ -1519,6 +1529,10 @@
["⏎", "Go to active search result"],
["+", "Expand all sections"],
["-", "Collapse all sections"],
+ // for the sake of brevity, we don't say "inherint impl blocks",
+ // although that would be more correct,
+ // since trait impl blocks are collapsed by -
+ ["_", "Collapse all sections, including impl blocks"],
].map(x => "<dt>" +
x[0].split(" ")
.map((y, index) => ((index & 1) === 0 ? "<kbd>" + y + "</kbd>" : " " + y + " "))
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index 7611372..ca13b89 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -418,7 +418,9 @@
<div id="help-button" tabindex="-1">
<a href="${rootPath}help.html"><span class="label">Help</span></a>
</div>
- <button id="toggle-all-docs"><span class="label">Summary</span></button>`;
+ <button id="toggle-all-docs"
+title="Collapse sections (shift-click to also collapse impl blocks)"><span
+class="label">Summary</span></button>`;
}
}
window.customElements.define("rustdoc-toolbar", RustdocToolbarElement);
diff --git a/src/tools/cargo b/src/tools/cargo
index 6833aa7..9b29697 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 6833aa715d724437dc1247d0166afe314ab6854e
+Subproject commit 9b296973b425ffb159e12cf3cd56580fd5c85382
diff --git a/src/tools/clippy/.github/workflows/feature_freeze.yml b/src/tools/clippy/.github/workflows/feature_freeze.yml
index 7ad58af..ec59be3 100644
--- a/src/tools/clippy/.github/workflows/feature_freeze.yml
+++ b/src/tools/clippy/.github/workflows/feature_freeze.yml
@@ -20,16 +20,26 @@
# of the pull request, as malicious code would be able to access the private
# GitHub token.
steps:
- - name: Check PR Changes
- id: pr-changes
- run: echo "::set-output name=changes::${{ toJson(github.event.pull_request.changed_files) }}"
-
- - name: Create Comment
- if: steps.pr-changes.outputs.changes != '[]'
- run: |
- # Use GitHub API to create a comment on the PR
- PR_NUMBER=${{ github.event.pull_request.number }}
- COMMENT="**Seems that you are trying to add a new lint!**\nWe are currently in a [feature freeze](https://doc.rust-lang.org/nightly/clippy/development/feature_freeze.html), so we are delaying all lint-adding PRs to September 18 and focusing on bugfixes.\nThanks a lot for your contribution, and sorry for the inconvenience.\nWith ❤ from the Clippy team\n\n@rustbot note Feature-freeze\n@rustbot blocked\n@rustbot label +A-lint\n"
- GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
- COMMENT_URL="https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments"
- curl -s -H "Authorization: token ${GITHUB_TOKEN}" -X POST $COMMENT_URL -d "{\"body\":\"$COMMENT\"}"
+ - name: Add freeze warning comment
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ PR_NUMBER: ${{ github.event.pull_request.number }}
+ run: |
+ COMMENT=$(echo "**Seems that you are trying to add a new lint!**\n\
+ \n\
+ We are currently in a [feature freeze](https://doc.rust-lang.org/nightly/clippy/development/feature_freeze.html), so we are delaying all lint-adding PRs to September 18 and [focusing on bugfixes](https://github.com/rust-lang/rust-clippy/issues/15086).\n\
+ \n\
+ Thanks a lot for your contribution, and sorry for the inconvenience.\n\
+ \n\
+ With ❤ from the Clippy team.\n\
+ \n\
+ @rustbot note Feature-freeze\n\
+ @rustbot blocked\n\
+ @rustbot label +A-lint"
+ )
+ curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
+ -H "Content-Type: application/vnd.github.raw+json" \
+ -X POST \
+ --data "{\"body\":\"${COMMENT}\"}" \
+ "https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments"
diff --git a/src/tools/clippy/.gitignore b/src/tools/clippy/.gitignore
index a7c25b290..36a4cdc 100644
--- a/src/tools/clippy/.gitignore
+++ b/src/tools/clippy/.gitignore
@@ -19,8 +19,10 @@
# Generated by Cargo
*Cargo.lock
+!/clippy_test_deps/Cargo.lock
/target
/clippy_lints/target
+/clippy_lints_internal/target
/clippy_utils/target
/clippy_dev/target
/lintcheck/target
diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs
index bd9e57c..2b2138d 100644
--- a/src/tools/clippy/clippy_dev/src/fmt.rs
+++ b/src/tools/clippy/clippy_dev/src/fmt.rs
@@ -3,7 +3,7 @@
walk_dir_no_dot_or_target,
};
use itertools::Itertools;
-use rustc_lexer::{TokenKind, tokenize};
+use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};
use std::fmt::Write;
use std::fs;
use std::io::{self, Read};
@@ -92,7 +92,7 @@ enum State {
let mut fields = Vec::new();
let mut state = State::Start;
- for (i, t) in tokenize(conf)
+ for (i, t) in tokenize(conf, FrontmatterAllowed::No)
.map(|x| {
let start = pos;
pos += x.len;
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index 5ed4c82..184fbbf 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -92,9 +92,11 @@ fn check_lit(&mut self, cx: &LateContext<'_>, _hir_id: HirId, lit: Lit, _negated
impl ApproxConstant {
fn check_known_consts(&self, cx: &LateContext<'_>, span: Span, s: symbol::Symbol, module: &str) {
let s = s.as_str();
- if s.parse::<f64>().is_ok() {
+ if let Ok(maybe_constant) = s.parse::<f64>() {
for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS {
- if is_approx_const(constant, s, min_digits) && msrv.is_none_or(|msrv| self.msrv.meets(cx, msrv)) {
+ if is_approx_const(constant, s, maybe_constant, min_digits)
+ && msrv.is_none_or(|msrv| self.msrv.meets(cx, msrv))
+ {
span_lint_and_help(
cx,
APPROX_CONSTANT,
@@ -112,18 +114,35 @@ fn check_known_consts(&self, cx: &LateContext<'_>, span: Span, s: symbol::Symbol
impl_lint_pass!(ApproxConstant => [APPROX_CONSTANT]);
+fn count_digits_after_dot(input: &str) -> usize {
+ input
+ .char_indices()
+ .find(|(_, ch)| *ch == '.')
+ .map_or(0, |(i, _)| input.len() - i - 1)
+}
+
/// Returns `false` if the number of significant figures in `value` are
/// less than `min_digits`; otherwise, returns true if `value` is equal
-/// to `constant`, rounded to the number of digits present in `value`.
+/// to `constant`, rounded to the number of significant digits present in `value`.
#[must_use]
-fn is_approx_const(constant: f64, value: &str, min_digits: usize) -> bool {
+fn is_approx_const(constant: f64, value: &str, f_value: f64, min_digits: usize) -> bool {
if value.len() <= min_digits {
+ // The value is not precise enough
false
- } else if constant.to_string().starts_with(value) {
- // The value is a truncated constant
+ } else if f_value.to_string().len() > min_digits && constant.to_string().starts_with(&f_value.to_string()) {
+ // The value represents the same value
true
} else {
- let round_const = format!("{constant:.*}", value.len() - 2);
+ // The value is a truncated constant
+
+ // Print constant with numeric formatting (`0`), with the length of `value` as minimum width
+ // (`value_len$`), and with the same precision as `value` (`.value_prec$`).
+ // See https://doc.rust-lang.org/std/fmt/index.html.
+ let round_const = format!(
+ "{constant:0value_len$.value_prec$}",
+ value_len = value.len(),
+ value_prec = count_digits_after_dot(value)
+ );
value == round_const
}
}
diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
index a9d3015..7b4cf03 100644
--- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -8,11 +8,11 @@
use clippy_utils::is_cfg_test;
use rustc_attr_data_structures::AttributeKind;
use rustc_hir::{
- Attribute, FieldDef, HirId, IsAuto, ImplItemId, Item, ItemKind, Mod, OwnerId, QPath, TraitItemId, TyKind,
- Variant, VariantData,
+ Attribute, FieldDef, HirId, ImplItemId, IsAuto, Item, ItemKind, Mod, OwnerId, QPath, TraitItemId, TyKind, Variant,
+ VariantData,
};
-use rustc_middle::ty::AssocKind;
use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::ty::AssocKind;
use rustc_session::impl_lint_pass;
use rustc_span::Ident;
@@ -469,13 +469,14 @@ struct CurItem<'a> {
/// This is implemented here because `rustc_hir` is not a dependency of
/// `clippy_config`.
fn convert_assoc_item_kind(cx: &LateContext<'_>, owner_id: OwnerId) -> SourceItemOrderingTraitAssocItemKind {
- let kind = cx.tcx.associated_item(owner_id.def_id).kind;
-
#[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
use SourceItemOrderingTraitAssocItemKind::*;
+
+ let kind = cx.tcx.associated_item(owner_id.def_id).kind;
+
match kind {
- AssocKind::Const{..} => Const,
- AssocKind::Type {..}=> Type,
+ AssocKind::Const { .. } => Const,
+ AssocKind::Type { .. } => Type,
AssocKind::Fn { .. } => Fn,
}
}
diff --git a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
index 9e09fb5..085029a 100644
--- a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
+++ b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
@@ -73,7 +73,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
diag.note(format!(
"`Arc<{arg_ty}>` is not `Send` and `Sync` as `{arg_ty}` is {reason}"
));
- diag.help("if the `Arc` will not used be across threads replace it with an `Rc`");
+ diag.help("if the `Arc` will not be used across threads replace it with an `Rc`");
diag.help(format!(
"otherwise make `{arg_ty}` `Send` and `Sync` or consider a wrapper type such as `Mutex`"
));
diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
index 4059f96..b9b5ced 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -36,6 +36,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
| sym::unused_braces
| sym::unused_import_braces
| sym::unused_imports
+ | sym::redundant_imports
)
{
return;
diff --git a/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs b/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs
index 769cc12..849de22 100644
--- a/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/confusing_method_to_numeric_cast.rs
@@ -59,9 +59,8 @@ fn get_const_name_and_ty_name(
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
// We allow casts from any function type to any function type.
- match cast_to.kind() {
- ty::FnDef(..) | ty::FnPtr(..) => return,
- _ => { /* continue to checks */ },
+ if cast_to.is_fn() {
+ return;
}
if let ty::FnDef(def_id, generics) = cast_from.kind()
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
index 55e27a0..c5d9643 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
@@ -3,7 +3,7 @@
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::Ty;
use super::{FN_TO_NUMERIC_CAST, utils};
@@ -13,23 +13,20 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
return;
};
- match cast_from.kind() {
- ty::FnDef(..) | ty::FnPtr(..) => {
- let mut applicability = Applicability::MaybeIncorrect;
+ if cast_from.is_fn() {
+ let mut applicability = Applicability::MaybeIncorrect;
- if to_nbits >= cx.tcx.data_layout.pointer_size().bits() && !cast_to.is_usize() {
- let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
- span_lint_and_sugg(
- cx,
- FN_TO_NUMERIC_CAST,
- expr.span,
- format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
- "try",
- format!("{from_snippet} as usize"),
- applicability,
- );
- }
- },
- _ => {},
+ if to_nbits >= cx.tcx.data_layout.pointer_size().bits() && !cast_to.is_usize() {
+ let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
+ span_lint_and_sugg(
+ cx,
+ FN_TO_NUMERIC_CAST,
+ expr.span,
+ format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
+ "try",
+ format!("{from_snippet} as usize"),
+ applicability,
+ );
+ }
}
}
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
index b22e8f4..43ee91a 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
@@ -3,18 +3,17 @@
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::Ty;
use super::FN_TO_NUMERIC_CAST_ANY;
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
// We allow casts from any function type to any function type.
- match cast_to.kind() {
- ty::FnDef(..) | ty::FnPtr(..) => return,
- _ => { /* continue to checks */ },
+ if cast_to.is_fn() {
+ return;
}
- if let ty::FnDef(..) | ty::FnPtr(..) = cast_from.kind() {
+ if cast_from.is_fn() {
let mut applicability = Applicability::MaybeIncorrect;
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "..", &mut applicability);
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
index 4da7920..9a2e44e 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
@@ -3,7 +3,7 @@
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::Ty;
use super::{FN_TO_NUMERIC_CAST_WITH_TRUNCATION, utils};
@@ -12,23 +12,20 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
let Some(to_nbits) = utils::int_ty_to_nbits(cx.tcx, cast_to) else {
return;
};
- match cast_from.kind() {
- ty::FnDef(..) | ty::FnPtr(..) => {
- let mut applicability = Applicability::MaybeIncorrect;
- let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
+ if cast_from.is_fn() {
+ let mut applicability = Applicability::MaybeIncorrect;
+ let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
- if to_nbits < cx.tcx.data_layout.pointer_size().bits() {
- span_lint_and_sugg(
- cx,
- FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
- expr.span,
- format!("casting function pointer `{from_snippet}` to `{cast_to}`, which truncates the value"),
- "try",
- format!("{from_snippet} as usize"),
- applicability,
- );
- }
- },
- _ => {},
+ if to_nbits < cx.tcx.data_layout.pointer_size().bits() {
+ span_lint_and_sugg(
+ cx,
+ FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
+ expr.span,
+ format!("casting function pointer `{from_snippet}` to `{cast_to}`, which truncates the value"),
+ "try",
+ format!("{from_snippet} as usize"),
+ applicability,
+ );
+ }
}
}
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
index 6f94491..ee0f3fa 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -4,10 +4,9 @@
use clippy_utils::sugg::Sugg;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, Mutability, QPath, TyKind};
-use rustc_hir_pretty::qpath_to_string;
use rustc_lint::LateContext;
use rustc_middle::ty;
-use rustc_span::sym;
+use rustc_span::{Span, sym};
use super::PTR_AS_PTR;
@@ -74,7 +73,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) {
let (help, final_suggestion) = if let Some(method) = omit_cast.corresponding_item() {
// don't force absolute path
- let method = qpath_to_string(&cx.tcx, method);
+ let method = snippet_with_applicability(cx, qpath_span_without_turbofish(method), "..", &mut app);
("try call directly", format!("{method}{turbofish}()"))
} else {
let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app);
@@ -96,3 +95,14 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Msrv) {
);
}
}
+
+fn qpath_span_without_turbofish(qpath: &QPath<'_>) -> Span {
+ if let QPath::Resolved(_, path) = qpath
+ && let [.., last_ident] = path.segments
+ && last_ident.args.is_some()
+ {
+ return qpath.span().shrink_to_lo().to(last_ident.ident.span);
+ }
+
+ qpath.span()
+}
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index d5d937d..518535e 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -110,7 +110,6 @@ fn check<'tcx>(
FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span,
FnKind::Closure => {
let header_span = body_span.with_hi(decl.output.span().lo());
- #[expect(clippy::range_plus_one)]
if let Some(range) = header_span.map_range(cx, |_, src, range| {
let mut idxs = src.get(range.clone())?.match_indices('|');
Some(range.start + idxs.next()?.0..range.start + idxs.next()?.0 + 1)
diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs
index 2791869..4bd3452 100644
--- a/src/tools/clippy/clippy_lints/src/copies.rs
+++ b/src/tools/clippy/clippy_lints/src/copies.rs
@@ -1,5 +1,6 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint, span_lint_and_note, span_lint_and_then};
+use clippy_utils::higher::has_let_expr;
use clippy_utils::source::{IntoSpan, SpanRangeExt, first_line_of_span, indent_of, reindent_multiline, snippet};
use clippy_utils::ty::{InteriorMut, needs_ordered_drop};
use clippy_utils::visitors::for_each_expr_without_closures;
@@ -11,7 +12,7 @@
use core::iter;
use core::ops::ControlFlow;
use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Node, Stmt, StmtKind, intravisit};
+use rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Node, Stmt, StmtKind, intravisit};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyCtxt;
use rustc_session::impl_lint_pass;
@@ -189,24 +190,13 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
}
}
-/// Checks if the given expression is a let chain.
-fn contains_let(e: &Expr<'_>) -> bool {
- match e.kind {
- ExprKind::Let(..) => true,
- ExprKind::Binary(op, lhs, rhs) if op.node == BinOpKind::And => {
- matches!(lhs.kind, ExprKind::Let(..)) || contains_let(rhs)
- },
- _ => false,
- }
-}
-
fn lint_if_same_then_else(cx: &LateContext<'_>, conds: &[&Expr<'_>], blocks: &[&Block<'_>]) -> bool {
let mut eq = SpanlessEq::new(cx);
blocks
.array_windows::<2>()
.enumerate()
.fold(true, |all_eq, (i, &[lhs, rhs])| {
- if eq.eq_block(lhs, rhs) && !contains_let(conds[i]) && conds.get(i + 1).is_none_or(|e| !contains_let(e)) {
+ if eq.eq_block(lhs, rhs) && !has_let_expr(conds[i]) && conds.get(i + 1).is_none_or(|e| !has_let_expr(e)) {
span_lint_and_note(
cx,
IF_SAME_THEN_ELSE,
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 062f7ce..49dd1bb 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -432,6 +432,11 @@ fn visit_fn(
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> Self::Result {
if let ExprKind::Block(block, _) = expr.kind
&& block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
+ && block
+ .span
+ .source_callee()
+ .and_then(|expr| expr.macro_def_id)
+ .is_none_or(|did| !self.cx.tcx.is_diagnostic_item(sym::pin_macro, did))
{
return ControlFlow::Break(());
}
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
index d55aeae..23e7c72 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
@@ -72,11 +72,11 @@ pub struct DisallowedMacros {
// When a macro is disallowed in an early pass, it's stored
// and emitted during the late pass. This happens for attributes.
- earlies: AttrStorage,
+ early_macro_cache: AttrStorage,
}
impl DisallowedMacros {
- pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf, earlies: AttrStorage) -> Self {
+ pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf, early_macro_cache: AttrStorage) -> Self {
let (disallowed, _) = create_disallowed_map(
tcx,
&conf.disallowed_macros,
@@ -89,7 +89,7 @@ pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf, earlies: AttrStorage) -> Self {
disallowed,
seen: FxHashSet::default(),
derive_src: None,
- earlies,
+ early_macro_cache,
}
}
@@ -130,7 +130,7 @@ fn check(&mut self, cx: &LateContext<'_>, span: Span, derive_src: Option<OwnerId
impl LateLintPass<'_> for DisallowedMacros {
fn check_crate(&mut self, cx: &LateContext<'_>) {
// once we check a crate in the late pass we can emit the early pass lints
- if let Some(attr_spans) = self.earlies.clone().0.get() {
+ if let Some(attr_spans) = self.early_macro_cache.clone().0.get() {
for span in attr_spans {
self.check(cx, *span, None);
}
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 22b781b..ea0da0d 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -1232,7 +1232,6 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
headers
}
-#[expect(clippy::range_plus_one)] // inclusive ranges aren't the same type
fn looks_like_refdef(doc: &str, range: Range<usize>) -> Option<Range<usize>> {
if range.end < range.start {
return None;
diff --git a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
index 4414aeb..f275740 100644
--- a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
@@ -92,8 +92,10 @@ pub struct EmptyWithBrackets {
impl LateLintPass<'_> for EmptyWithBrackets {
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
+ // FIXME: handle `struct $name {}`
if let ItemKind::Struct(ident, _, var_data) = &item.kind
&& !item.span.from_expansion()
+ && !ident.span.from_expansion()
&& has_brackets(var_data)
&& let span_after_ident = item.span.with_lo(ident.span.hi())
&& has_no_fields(cx, var_data, span_after_ident)
@@ -116,10 +118,12 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
}
fn check_variant(&mut self, cx: &LateContext<'_>, variant: &Variant<'_>) {
- // the span of the parentheses/braces
- let span_after_ident = variant.span.with_lo(variant.ident.span.hi());
-
- if has_no_fields(cx, &variant.data, span_after_ident) {
+ // FIXME: handle `$name {}`
+ if !variant.span.from_expansion()
+ && !variant.ident.span.from_expansion()
+ && let span_after_ident = variant.span.with_lo(variant.ident.span.hi())
+ && has_no_fields(cx, &variant.data, span_after_ident)
+ {
match variant.data {
VariantData::Struct { .. } => {
// Empty struct variants can be linted immediately
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index db2fea1..fc224fa 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -1,8 +1,8 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_hir;
use rustc_abi::ExternAbi;
-use rustc_hir::{Body, FnDecl, HirId, HirIdSet, Node, Pat, PatKind, intravisit};
use rustc_hir::def::DefKind;
+use rustc_hir::{Body, FnDecl, HirId, HirIdSet, Node, Pat, PatKind, intravisit};
use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::mir::FakeReadCause;
@@ -87,16 +87,14 @@ fn check_fn(
let mut trait_self_ty = None;
match cx.tcx.def_kind(parent_id) {
// If the method is an impl for a trait, don't warn.
- DefKind::Impl { of_trait: true } => {
- return
- }
+ DefKind::Impl { of_trait: true } => return,
// find `self` ty for this trait if relevant
DefKind::Trait => {
trait_self_ty = Some(TraitRef::identity(cx.tcx, parent_id.to_def_id()).self_ty());
- }
+ },
- _ => {}
+ _ => {},
}
let mut v = EscapeDelegate {
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 0288747..9b62767 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -29,12 +29,6 @@
/// Needlessly creating a closure adds code for no benefit
/// and gives the optimizer more work.
///
- /// ### Known problems
- /// If creating the closure inside the closure has a side-
- /// effect then moving the closure creation out will change when that side-
- /// effect runs.
- /// See [#1439](https://github.com/rust-lang/rust-clippy/issues/1439) for more details.
- ///
/// ### Example
/// ```rust,ignore
/// xs.map(|x| foo(x))
diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
index 552cd72..fdfcbb5 100644
--- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
+++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
@@ -64,8 +64,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
}
fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Span) {
- use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::Expr;
+ use rustc_hir::intravisit::{self, Visitor};
struct FindPanicUnwrap<'a, 'tcx> {
lcx: &'a LateContext<'tcx>,
@@ -96,10 +96,12 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
}
}
- for impl_item in cx.tcx.associated_items(item_def_id)
+ for impl_item in cx
+ .tcx
+ .associated_items(item_def_id)
.filter_by_name_unhygienic_and_kind(sym::from, ty::AssocTag::Fn)
{
- let impl_item_def_id= impl_item.def_id.expect_local();
+ let impl_item_def_id = impl_item.def_id.expect_local();
// check the body for `begin_panic` or `unwrap`
let body = cx.tcx.hir_body_owned_by(impl_item_def_id);
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 16c58ec..a251f15 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -17,7 +17,7 @@
FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions,
FormatPlaceholder, FormatTrait,
};
-use rustc_attr_data_structures::RustcVersion;
+use rustc_attr_data_structures::{AttributeKind, RustcVersion, find_attr};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::Applicability;
use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode};
@@ -30,7 +30,6 @@
use rustc_span::{Span, Symbol, sym};
use rustc_trait_selection::infer::TyCtxtInferExt;
use rustc_trait_selection::traits::{Obligation, ObligationCause, Selection, SelectionContext};
-use rustc_attr_data_structures::{AttributeKind, find_attr};
declare_clippy_lint! {
/// ### What it does
@@ -129,6 +128,7 @@
/// # let width = 1;
/// # let prec = 2;
/// format!("{}", var);
+ /// format!("{:?}", var);
/// format!("{v:?}", v = var);
/// format!("{0} {0}", var);
/// format!("{0:1$}", var, width);
@@ -141,6 +141,7 @@
/// # let prec = 2;
/// format!("{var}");
/// format!("{var:?}");
+ /// format!("{var:?}");
/// format!("{var} {var}");
/// format!("{var:width$}");
/// format!("{var:.prec$}");
@@ -164,7 +165,7 @@
/// nothing will be suggested, e.g. `println!("{0}={1}", var, 1+2)`.
#[clippy::version = "1.66.0"]
pub UNINLINED_FORMAT_ARGS,
- style,
+ pedantic,
"using non-inlined variables in `format!` calls"
}
@@ -657,7 +658,10 @@ fn has_pointer_debug(&mut self, ty: Ty<'tcx>, depth: usize) -> bool {
};
let selection = SelectionContext::new(&infcx).select(&obligation);
let derived = if let Ok(Some(Selection::UserDefined(data))) = selection {
- find_attr!(tcx.get_all_attrs(data.impl_def_id), AttributeKind::AutomaticallyDerived(..))
+ find_attr!(
+ tcx.get_all_attrs(data.impl_def_id),
+ AttributeKind::AutomaticallyDerived(..)
+ )
} else {
false
};
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index 85b40ba..1da6952 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -9,7 +9,7 @@
use rustc_errors::Applicability;
use rustc_hir::intravisit::{Visitor, walk_path};
use rustc_hir::{
- FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemId, Item, ItemKind, PatKind, Path,
+ FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemId, ImplItemKind, Item, ItemKind, PatKind, Path,
PathSegment, Ty, TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index d959981..b8d0cec 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -10,7 +10,7 @@
use clippy_utils::attrs::is_proc_macro;
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
-use clippy_utils::source::SpanRangeExt;
+use clippy_utils::source::snippet_indent;
use clippy_utils::ty::is_must_use_ty;
use clippy_utils::visitors::for_each_expr_without_closures;
use clippy_utils::{return_ty, trait_ref_of_method};
@@ -28,6 +28,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
if let hir::ItemKind::Fn {
ref sig,
body: ref body_id,
+ ident,
..
} = item.kind
{
@@ -51,8 +52,8 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
sig.decl,
cx.tcx.hir_body(*body_id),
item.span,
+ ident.span,
item.owner_id,
- item.span.with_hi(sig.decl.output.span().hi()),
"this function could have a `#[must_use]` attribute",
);
}
@@ -84,8 +85,8 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
sig.decl,
cx.tcx.hir_body(*body_id),
item.span,
+ item.ident.span,
item.owner_id,
- item.span.with_hi(sig.decl.output.span().hi()),
"this method could have a `#[must_use]` attribute",
);
}
@@ -120,8 +121,8 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
sig.decl,
body,
item.span,
+ item.ident.span,
item.owner_id,
- item.span.with_hi(sig.decl.output.span().hi()),
"this method could have a `#[must_use]` attribute",
);
}
@@ -198,8 +199,8 @@ fn check_must_use_candidate<'tcx>(
decl: &'tcx hir::FnDecl<'_>,
body: &'tcx hir::Body<'_>,
item_span: Span,
+ ident_span: Span,
item_id: hir::OwnerId,
- fn_span: Span,
msg: &'static str,
) {
if has_mutable_arg(cx, body)
@@ -208,18 +209,18 @@ fn check_must_use_candidate<'tcx>(
|| returns_unit(decl)
|| !cx.effective_visibilities.is_exported(item_id.def_id)
|| is_must_use_ty(cx, return_ty(cx, item_id))
+ || item_span.from_expansion()
{
return;
}
- span_lint_and_then(cx, MUST_USE_CANDIDATE, fn_span, msg, |diag| {
- if let Some(snippet) = fn_span.get_source_text(cx) {
- diag.span_suggestion(
- fn_span,
- "add the attribute",
- format!("#[must_use] {snippet}"),
- Applicability::MachineApplicable,
- );
- }
+ span_lint_and_then(cx, MUST_USE_CANDIDATE, ident_span, msg, |diag| {
+ let indent = snippet_indent(cx, item_span).unwrap_or_default();
+ diag.span_suggestion(
+ item_span.shrink_to_lo(),
+ "add the attribute",
+ format!("#[must_use] \n{indent}"),
+ Applicability::MachineApplicable,
+ );
});
}
diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
index 9e94280..7158f94 100644
--- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
@@ -5,7 +5,8 @@
use clippy_utils::source::snippet_with_context;
use clippy_utils::sugg::Sugg;
use clippy_utils::{
- contains_return, higher, is_else_clause, is_in_const_context, is_res_lang_ctor, path_res, peel_blocks,
+ contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, is_res_lang_ctor,
+ path_res, peel_blocks,
};
use rustc_errors::Applicability;
use rustc_hir::LangItem::{OptionNone, OptionSome};
@@ -92,6 +93,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
expr.span,
format!("this could be simplified with `bool::{method_name}`"),
|diag| {
+ if expr_adjustment_requires_coercion(cx, then_arg) {
+ return;
+ }
+
let mut app = Applicability::MachineApplicable;
let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app)
.maybe_paren()
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
index 5d0bd3e..116d63c 100644
--- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -1,10 +1,11 @@
use clippy_config::Conf;
-use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_in_test;
+use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::msrvs::Msrv;
+use clippy_utils::{is_in_const_context, is_in_test};
use rustc_attr_data_structures::{RustcVersion, StabilityLevel, StableSince};
use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::{Expr, ExprKind, HirId, QPath};
+use rustc_hir::def::DefKind;
+use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyCtxt;
use rustc_session::impl_lint_pass;
@@ -33,15 +34,54 @@
///
/// To fix this problem, either increase your MSRV or use another item
/// available in your current MSRV.
+ ///
+ /// You can also locally change the MSRV that should be checked by Clippy,
+ /// for example if a feature in your crate (e.g., `modern_compiler`) should
+ /// allow you to use an item:
+ ///
+ /// ```no_run
+ /// //! This crate has a MSRV of 1.3.0, but we also have an optional feature
+ /// //! `sleep_well` which requires at least Rust 1.4.0.
+ ///
+ /// // When the `sleep_well` feature is set, do not warn for functions available
+ /// // in Rust 1.4.0 and below.
+ /// #![cfg_attr(feature = "sleep_well", clippy::msrv = "1.4.0")]
+ ///
+ /// use std::time::Duration;
+ ///
+ /// #[cfg(feature = "sleep_well")]
+ /// fn sleep_for_some_time() {
+ /// std::thread::sleep(Duration::new(1, 0)); // Will not trigger the lint
+ /// }
+ /// ```
+ ///
+ /// You can also increase the MSRV in tests, by using:
+ ///
+ /// ```no_run
+ /// // Use a much higher MSRV for tests while keeping the main one low
+ /// #![cfg_attr(test, clippy::msrv = "1.85.0")]
+ ///
+ /// #[test]
+ /// fn my_test() {
+ /// // The tests can use items introduced in Rust 1.85.0 and lower
+ /// // without triggering the `incompatible_msrv` lint.
+ /// }
+ /// ```
#[clippy::version = "1.78.0"]
pub INCOMPATIBLE_MSRV,
suspicious,
"ensures that all items used in the crate are available for the current MSRV"
}
+#[derive(Clone, Copy)]
+enum Availability {
+ FeatureEnabled,
+ Since(RustcVersion),
+}
+
pub struct IncompatibleMsrv {
msrv: Msrv,
- is_above_msrv: FxHashMap<DefId, RustcVersion>,
+ availability_cache: FxHashMap<(DefId, bool), Availability>,
check_in_tests: bool,
}
@@ -51,38 +91,50 @@ impl IncompatibleMsrv {
pub fn new(conf: &'static Conf) -> Self {
Self {
msrv: conf.msrv,
- is_above_msrv: FxHashMap::default(),
+ availability_cache: FxHashMap::default(),
check_in_tests: conf.check_incompatible_msrv_in_tests,
}
}
- fn get_def_id_version(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> RustcVersion {
- if let Some(version) = self.is_above_msrv.get(&def_id) {
- return *version;
+ /// Returns the availability of `def_id`, whether it is enabled through a feature or
+ /// available since a given version (the default being Rust 1.0.0). `needs_const` requires
+ /// the `const`-stability to be looked up instead of the stability in non-`const` contexts.
+ fn get_def_id_availability(&mut self, tcx: TyCtxt<'_>, def_id: DefId, needs_const: bool) -> Availability {
+ if let Some(availability) = self.availability_cache.get(&(def_id, needs_const)) {
+ return *availability;
}
- let version = if let Some(version) = tcx
- .lookup_stability(def_id)
- .and_then(|stability| match stability.level {
- StabilityLevel::Stable {
- since: StableSince::Version(version),
- ..
- } => Some(version),
- _ => None,
- }) {
- version
- } else if let Some(parent_def_id) = tcx.opt_parent(def_id) {
- self.get_def_id_version(tcx, parent_def_id)
+ let (feature, stability_level) = if needs_const {
+ tcx.lookup_const_stability(def_id)
+ .map(|stability| (stability.feature, stability.level))
+ .unzip()
} else {
- RustcVersion {
+ tcx.lookup_stability(def_id)
+ .map(|stability| (stability.feature, stability.level))
+ .unzip()
+ };
+ let version = if feature.is_some_and(|feature| tcx.features().enabled(feature)) {
+ Availability::FeatureEnabled
+ } else if let Some(StableSince::Version(version)) =
+ stability_level.as_ref().and_then(StabilityLevel::stable_since)
+ {
+ Availability::Since(version)
+ } else if needs_const {
+ // Fallback to regular stability
+ self.get_def_id_availability(tcx, def_id, false)
+ } else if let Some(parent_def_id) = tcx.opt_parent(def_id) {
+ self.get_def_id_availability(tcx, parent_def_id, needs_const)
+ } else {
+ Availability::Since(RustcVersion {
major: 1,
minor: 0,
patch: 0,
- }
+ })
};
- self.is_above_msrv.insert(def_id, version);
+ self.availability_cache.insert((def_id, needs_const), version);
version
}
+ /// Emit lint if `def_id`, associated with `node` and `span`, is below the current MSRV.
fn emit_lint_if_under_msrv(&mut self, cx: &LateContext<'_>, def_id: DefId, node: HirId, span: Span) {
if def_id.is_local() {
// We don't check local items since their MSRV is supposed to always be valid.
@@ -108,18 +160,28 @@ fn emit_lint_if_under_msrv(&mut self, cx: &LateContext<'_>, def_id: DefId, node:
return;
}
+ let needs_const = cx.enclosing_body.is_some()
+ && is_in_const_context(cx)
+ && matches!(cx.tcx.def_kind(def_id), DefKind::AssocFn | DefKind::Fn);
+
if (self.check_in_tests || !is_in_test(cx.tcx, node))
&& let Some(current) = self.msrv.current(cx)
- && let version = self.get_def_id_version(cx.tcx, def_id)
+ && let Availability::Since(version) = self.get_def_id_availability(cx.tcx, def_id, needs_const)
&& version > current
{
- span_lint(
+ span_lint_and_then(
cx,
INCOMPATIBLE_MSRV,
span,
format!(
- "current MSRV (Minimum Supported Rust Version) is `{current}` but this item is stable since `{version}`"
+ "current MSRV (Minimum Supported Rust Version) is `{current}` but this item is stable{} since `{version}`",
+ if needs_const { " in a `const` context" } else { "" },
),
+ |diag| {
+ if is_under_cfg_attribute(cx, node) {
+ diag.note_once("you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute");
+ }
+ },
);
}
}
@@ -133,17 +195,38 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
self.emit_lint_if_under_msrv(cx, method_did, expr.hir_id, span);
}
},
- ExprKind::Call(call, _) => {
- // Desugaring into function calls by the compiler will use `QPath::LangItem` variants. Those should
- // not be linted as they will not be generated in older compilers if the function is not available,
- // and the compiler is allowed to call unstable functions.
- if let ExprKind::Path(qpath @ (QPath::Resolved(..) | QPath::TypeRelative(..))) = call.kind
- && let Some(path_def_id) = cx.qpath_res(&qpath, call.hir_id).opt_def_id()
- {
- self.emit_lint_if_under_msrv(cx, path_def_id, expr.hir_id, call.span);
+ // Desugaring into function calls by the compiler will use `QPath::LangItem` variants. Those should
+ // not be linted as they will not be generated in older compilers if the function is not available,
+ // and the compiler is allowed to call unstable functions.
+ ExprKind::Path(qpath @ (QPath::Resolved(..) | QPath::TypeRelative(..))) => {
+ if let Some(path_def_id) = cx.qpath_res(&qpath, expr.hir_id).opt_def_id() {
+ self.emit_lint_if_under_msrv(cx, path_def_id, expr.hir_id, expr.span);
}
},
_ => {},
}
}
+
+ fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &'tcx hir::Ty<'tcx, AmbigArg>) {
+ if let hir::TyKind::Path(qpath @ (QPath::Resolved(..) | QPath::TypeRelative(..))) = hir_ty.kind
+ && let Some(ty_def_id) = cx.qpath_res(&qpath, hir_ty.hir_id).opt_def_id()
+ // `CStr` and `CString` have been moved around but have been available since Rust 1.0.0
+ && !matches!(cx.tcx.get_diagnostic_name(ty_def_id), Some(sym::cstr_type | sym::cstring_type))
+ {
+ self.emit_lint_if_under_msrv(cx, ty_def_id, hir_ty.hir_id, hir_ty.span);
+ }
+ }
+}
+
+/// Heuristic checking if the node `hir_id` is under a `#[cfg()]` or `#[cfg_attr()]`
+/// attribute.
+fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool {
+ cx.tcx.hir_parent_id_iter(hir_id).any(|id| {
+ cx.tcx.hir_attrs(id).iter().any(|attr| {
+ matches!(
+ attr.ident().map(|ident| ident.name),
+ Some(sym::cfg_trace | sym::cfg_attr_trace)
+ )
+ })
+ })
}
diff --git a/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs b/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs
index 7a75151..a159f61 100644
--- a/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs
+++ b/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs
@@ -1,13 +1,12 @@
-use crate::methods::method_call;
use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{peel_blocks, sym};
+use clippy_utils::source::SpanRangeExt;
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::{peel_blocks, peel_hir_expr_while, sym};
use rustc_ast::LitKind;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
use rustc_session::declare_lint_pass;
-use rustc_span::{BytePos, Span};
declare_clippy_lint! {
/// ### What it does
@@ -43,53 +42,58 @@
declare_lint_pass!(IneffectiveOpenOptions => [INEFFECTIVE_OPEN_OPTIONS]);
-fn index_if_arg_is_boolean(args: &[Expr<'_>], call_span: Span) -> Option<Span> {
- if let [arg] = args
- && let ExprKind::Lit(lit) = peel_blocks(arg).kind
- && lit.node == LitKind::Bool(true)
- {
- // The `.` is not included in the span so we cheat a little bit to include it as well.
- Some(call_span.with_lo(call_span.lo() - BytePos(1)))
- } else {
- None
- }
-}
-
impl<'tcx> LateLintPass<'tcx> for IneffectiveOpenOptions {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
- let Some((sym::open, mut receiver, [_arg], _, _)) = method_call(expr) else {
- return;
- };
- let receiver_ty = cx.typeck_results().expr_ty(receiver);
- match receiver_ty.peel_refs().kind() {
- ty::Adt(adt, _) if cx.tcx.is_diagnostic_item(sym::FsOpenOptions, adt.did()) => {},
- _ => return,
- }
-
- let mut append = None;
- let mut write = None;
-
- while let Some((name, recv, args, _, span)) = method_call(receiver) {
- if name == sym::append {
- append = index_if_arg_is_boolean(args, span);
- } else if name == sym::write {
- write = index_if_arg_is_boolean(args, span);
- }
- receiver = recv;
- }
-
- if let Some(write_span) = write
- && append.is_some()
+ if let ExprKind::MethodCall(name, recv, [_], _) = expr.kind
+ && name.ident.name == sym::open
+ && !expr.span.from_expansion()
+ && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv).peel_refs(), sym::FsOpenOptions)
{
- span_lint_and_sugg(
- cx,
- INEFFECTIVE_OPEN_OPTIONS,
- write_span,
- "unnecessary use of `.write(true)` because there is `.append(true)`",
- "remove `.write(true)`",
- String::new(),
- Applicability::MachineApplicable,
- );
+ let mut append = false;
+ let mut write = None;
+ peel_hir_expr_while(recv, |e| {
+ if let ExprKind::MethodCall(name, recv, args, call_span) = e.kind
+ && !e.span.from_expansion()
+ {
+ if let [arg] = args
+ && let ExprKind::Lit(lit) = peel_blocks(arg).kind
+ && matches!(lit.node, LitKind::Bool(true))
+ && !arg.span.from_expansion()
+ && !lit.span.from_expansion()
+ {
+ match name.ident.name {
+ sym::append => append = true,
+ sym::write
+ if let Some(range) = call_span.map_range(cx, |_, text, range| {
+ if text.get(..range.start)?.ends_with('.') {
+ Some(range.start - 1..range.end)
+ } else {
+ None
+ }
+ }) =>
+ {
+ write = Some(call_span.with_lo(range.start));
+ },
+ _ => {},
+ }
+ }
+ Some(recv)
+ } else {
+ None
+ }
+ });
+
+ if append && let Some(write_span) = write {
+ span_lint_and_sugg(
+ cx,
+ INEFFECTIVE_OPEN_OPTIONS,
+ write_span,
+ "unnecessary use of `.write(true)` because there is `.append(true)`",
+ "remove `.write(true)`",
+ String::new(),
+ Applicability::MachineApplicable,
+ );
+ }
}
}
}
diff --git a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
index e79fcec..f7cdf05 100644
--- a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
+++ b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
@@ -52,13 +52,17 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if !cx.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) {
return;
}
- for ii in cx.tcx.associated_items(item.owner_id.def_id)
+ for ii in cx
+ .tcx
+ .associated_items(item.owner_id.def_id)
.filter_by_name_unhygienic_and_kind(sym::Error, AssocTag::Type)
{
let ii_ty = cx.tcx.type_of(ii.def_id).instantiate_identity();
if !ii_ty.is_inhabited_from(cx.tcx, ii.def_id, cx.typing_env()) {
let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id()));
- let ii_ty_span = cx.tcx.hir_node_by_def_id(ii.def_id.expect_local())
+ let ii_ty_span = cx
+ .tcx
+ .hir_node_by_def_id(ii.def_id.expect_local())
.expect_impl_item()
.expect_type()
.span;
diff --git a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
index 9c91cf6..95e16aa 100644
--- a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
+++ b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
@@ -8,6 +8,7 @@
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, QPath, TyKind, Variant, VariantData};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
+use rustc_span::MacroKind;
use rustc_span::symbol::Symbol;
declare_clippy_lint! {
@@ -502,7 +503,8 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
);
}
- if both_are_public && item_camel.len() > mod_camel.len() {
+ let is_macro_rule = matches!(item.kind, ItemKind::Macro(_, _, MacroKind::Bang));
+ if both_are_public && item_camel.len() > mod_camel.len() && !is_macro_rule {
let matching = count_match_start(mod_camel, &item_camel);
let rmatching = count_match_end(mod_camel, &item_camel);
let nchars = mod_camel.chars().count();
diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
index 03038f0..b89f91f 100644
--- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
@@ -139,11 +139,17 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) {
// We can't check inherent impls for slices, but we know that they have an `iter(_mut)` method
ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some()
})
- && let Some(iter_assoc_span) = cx.tcx.associated_items(item.owner_id)
+ && let Some(iter_assoc_span) = cx
+ .tcx
+ .associated_items(item.owner_id)
.filter_by_name_unhygienic_and_kind(sym::IntoIter, ty::AssocTag::Type)
.next()
.map(|assoc_item| {
- cx.tcx.hir_node_by_def_id(assoc_item.def_id.expect_local()).expect_impl_item().expect_type().span
+ cx.tcx
+ .hir_node_by_def_id(assoc_item.def_id.expect_local())
+ .expect_impl_item()
+ .expect_type()
+ .span
})
&& is_ty_exported(cx, ty)
{
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index e85d779..c2b7394 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -1,5 +1,6 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_no_std_crate;
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_copy};
use rustc_errors::Applicability;
@@ -83,7 +84,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
let mut difference = variants_size[0].size - variants_size[1].size;
if difference > self.maximum_size_difference_allowed {
- let help_text = "consider boxing the large fields to reduce the total size of the enum";
+ let help_text = "consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum";
span_lint_and_then(
cx,
LARGE_ENUM_VARIANT,
@@ -117,7 +118,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
ident.span,
"boxing a variant would require the type no longer be `Copy`",
);
- } else {
+ } else if !is_no_std_crate(cx) {
let sugg: Vec<(Span, String)> = variants_size[0]
.fields_size
.iter()
diff --git a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
index b3c63f0..42c6365 100644
--- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
@@ -1,7 +1,8 @@
use clippy_config::Conf;
-use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_from_proc_macro;
use clippy_utils::msrvs::{self, Msrv};
-use clippy_utils::{get_parent_expr, is_from_proc_macro};
+use clippy_utils::source::SpanRangeExt;
use hir::def_id::DefId;
use rustc_errors::Applicability;
use rustc_hir as hir;
@@ -102,39 +103,45 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
}
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
- let ExprKind::Path(qpath) = &expr.kind else {
- return;
- };
-
// `std::<integer>::<CONST>` check
- let (span, sugg, msg) = if let QPath::Resolved(None, path) = qpath
+ let (sugg, msg) = if let ExprKind::Path(qpath) = &expr.kind
+ && let QPath::Resolved(None, path) = qpath
&& let Some(def_id) = path.res.opt_def_id()
&& is_numeric_const(cx, def_id)
- && let def_path = cx.get_def_path(def_id)
- && let [.., mod_name, name] = &*def_path
+ && let [.., mod_name, name] = &*cx.get_def_path(def_id)
// Skip linting if this usage looks identical to the associated constant,
// since this would only require removing a `use` import (which is already linted).
&& !is_numeric_const_path_canonical(path, [*mod_name, *name])
{
(
- expr.span,
- format!("{mod_name}::{name}"),
+ vec![(expr.span, format!("{mod_name}::{name}"))],
"usage of a legacy numeric constant",
)
// `<integer>::xxx_value` check
- } else if let QPath::TypeRelative(_, last_segment) = qpath
- && let Some(def_id) = cx.qpath_res(qpath, expr.hir_id).opt_def_id()
- && let Some(par_expr) = get_parent_expr(cx, expr)
- && let ExprKind::Call(_, []) = par_expr.kind
+ } else if let ExprKind::Call(func, []) = &expr.kind
+ && let ExprKind::Path(qpath) = &func.kind
+ && let QPath::TypeRelative(ty, last_segment) = qpath
+ && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id()
&& is_integer_method(cx, def_id)
{
- let name = last_segment.ident.name.as_str();
-
- (
- last_segment.ident.span.with_hi(par_expr.span.hi()),
- name[..=2].to_ascii_uppercase(),
- "usage of a legacy numeric method",
- )
+ let mut sugg = vec![
+ // Replace the function name up to the end by the constant name
+ (
+ last_segment.ident.span.to(expr.span.shrink_to_hi()),
+ last_segment.ident.name.as_str()[..=2].to_ascii_uppercase(),
+ ),
+ ];
+ let before_span = expr.span.shrink_to_lo().until(ty.span);
+ if !before_span.is_empty() {
+ // Remove everything before the type name
+ sugg.push((before_span, String::new()));
+ }
+ // Use `::` between the type name and the constant
+ let between_span = ty.span.shrink_to_hi().until(last_segment.ident.span);
+ if !between_span.check_source_text(cx, |s| s == "::") {
+ sugg.push((between_span, String::from("::")));
+ }
+ (sugg, "usage of a legacy numeric method")
} else {
return;
};
@@ -143,9 +150,8 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tc
&& self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
&& !is_from_proc_macro(cx, expr)
{
- span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
- diag.span_suggestion_verbose(
- span,
+ span_lint_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.span, msg, |diag| {
+ diag.multipart_suggestion_verbose(
"use the associated constant instead",
sugg,
Applicability::MaybeIncorrect,
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 1bf0348..6beddc1 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -10,9 +10,9 @@
use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::{
- BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind,
- ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatExprKind, PatKind, PathSegment, PrimTy,
- QPath, TraitItemId, TyKind,
+ BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind, ImplicitSelfKind,
+ Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatExprKind, PatKind, PathSegment, PrimTy, QPath, TraitItemId,
+ TyKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, FnSig, Ty};
@@ -266,11 +266,14 @@ fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {
}
fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) {
- fn is_named_self(cx: &LateContext<'_>, item: &TraitItemId, name: Symbol) -> bool {
+ fn is_named_self(cx: &LateContext<'_>, item: TraitItemId, name: Symbol) -> bool {
cx.tcx.item_name(item.owner_id) == name
&& matches!(
cx.tcx.fn_arg_idents(item.owner_id),
- [Some(Ident { name: kw::SelfLower, .. })],
+ [Some(Ident {
+ name: kw::SelfLower,
+ ..
+ })],
)
}
@@ -284,7 +287,7 @@ fn fill_trait_set(traitt: DefId, set: &mut DefIdSet, cx: &LateContext<'_>) {
}
if cx.effective_visibilities.is_exported(visited_trait.owner_id.def_id)
- && trait_items.iter().any(|i| is_named_self(cx, i, sym::len))
+ && trait_items.iter().any(|&i| is_named_self(cx, i, sym::len))
{
let mut current_and_super_traits = DefIdSet::default();
fill_trait_set(visited_trait.owner_id.to_def_id(), &mut current_and_super_traits, cx);
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 7837b18..972b0b1 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -39,7 +39,9 @@ pub(super) fn check<'tcx>(
var: canonical_id,
indexed_mut: FxHashSet::default(),
indexed_indirectly: FxHashMap::default(),
+ unnamed_indexed_indirectly: false,
indexed_directly: FxIndexMap::default(),
+ unnamed_indexed_directly: false,
referenced: FxHashSet::default(),
nonindex: false,
prefer_mutable: false,
@@ -47,7 +49,11 @@ pub(super) fn check<'tcx>(
walk_expr(&mut visitor, body);
// linting condition: we only indexed one variable, and indexed it directly
- if visitor.indexed_indirectly.is_empty() && visitor.indexed_directly.len() == 1 {
+ if visitor.indexed_indirectly.is_empty()
+ && !visitor.unnamed_indexed_indirectly
+ && !visitor.unnamed_indexed_directly
+ && visitor.indexed_directly.len() == 1
+ {
let (indexed, (indexed_extent, indexed_ty)) = visitor
.indexed_directly
.into_iter()
@@ -217,6 +223,7 @@ fn is_end_eq_array_len<'tcx>(
false
}
+#[expect(clippy::struct_excessive_bools)]
struct VarVisitor<'a, 'tcx> {
/// context reference
cx: &'a LateContext<'tcx>,
@@ -226,9 +233,13 @@ struct VarVisitor<'a, 'tcx> {
indexed_mut: FxHashSet<Symbol>,
/// indirectly indexed variables (`v[(i + 4) % N]`), the extend is `None` for global
indexed_indirectly: FxHashMap<Symbol, Option<region::Scope>>,
+ /// indirectly indexed literals, like `[1, 2, 3][(i + 4) % N]`
+ unnamed_indexed_indirectly: bool,
/// subset of `indexed` of vars that are indexed directly: `v[i]`
/// this will not contain cases like `v[calc_index(i)]` or `v[(i + 4) % N]`
indexed_directly: FxIndexMap<Symbol, (Option<region::Scope>, Ty<'tcx>)>,
+ /// directly indexed literals, like `[1, 2, 3][i]`
+ unnamed_indexed_directly: bool,
/// Any names that are used outside an index operation.
/// Used to detect things like `&mut vec` used together with `vec[i]`
referenced: FxHashSet<Symbol>,
@@ -242,6 +253,7 @@ struct VarVisitor<'a, 'tcx> {
impl<'tcx> VarVisitor<'_, 'tcx> {
fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) -> bool {
+ let index_used_directly = matches!(idx.kind, ExprKind::Path(_));
if let ExprKind::Path(ref seqpath) = seqexpr.kind
// the indexed container is referenced by a name
&& let QPath::Resolved(None, seqvar) = *seqpath
@@ -251,7 +263,6 @@ fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Ex
if self.prefer_mutable {
self.indexed_mut.insert(seqvar.segments[0].ident.name);
}
- let index_used_directly = matches!(idx.kind, ExprKind::Path(_));
let res = self.cx.qpath_res(seqpath, seqexpr.hir_id);
match res {
Res::Local(hir_id) => {
@@ -286,6 +297,13 @@ fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Ex
},
_ => (),
}
+ } else if let ExprKind::Repeat(..) | ExprKind::Array(..) = seqexpr.kind {
+ if index_used_directly {
+ self.unnamed_indexed_directly = true;
+ } else {
+ self.unnamed_indexed_indirectly = true;
+ }
+ return false;
}
true
}
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 69c84bc..8a253ae 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -6,9 +6,11 @@
use clippy_utils::source::snippet;
use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
use rustc_errors::Applicability;
-use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind, StructTailExpr};
+use rustc_hir::{
+ Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Node, Pat, Stmt, StmtKind, StructTailExpr,
+};
use rustc_lint::LateContext;
-use rustc_span::{Span, sym};
+use rustc_span::{BytePos, Span, sym};
use std::iter::once;
use std::ops::ControlFlow;
@@ -20,7 +22,7 @@ pub(super) fn check<'tcx>(
for_loop: Option<&ForLoop<'_>>,
) {
match never_loop_block(cx, block, &mut Vec::new(), loop_id) {
- NeverLoopResult::Diverging => {
+ NeverLoopResult::Diverging { ref break_spans } => {
span_lint_and_then(cx, NEVER_LOOP, span, "this loop never actually loops", |diag| {
if let Some(ForLoop {
arg: iterator,
@@ -38,10 +40,15 @@ pub(super) fn check<'tcx>(
Applicability::Unspecified
};
- diag.span_suggestion_verbose(
+ let mut suggestions = vec![(
for_span.with_hi(iterator.span.hi()),
- "if you need the first element of the iterator, try writing",
for_to_if_let_sugg(cx, iterator, pat),
+ )];
+ // Make sure to clear up the diverging sites when we remove a loopp.
+ suggestions.extend(break_spans.iter().map(|span| (*span, String::new())));
+ diag.multipart_suggestion_verbose(
+ "if you need the first element of the iterator, try writing",
+ suggestions,
app,
);
}
@@ -70,22 +77,22 @@ fn contains_any_break_or_continue(block: &Block<'_>) -> bool {
/// The first two bits of information are in this enum, and the last part is in the
/// `local_labels` variable, which contains a list of `(block_id, reachable)` pairs ordered by
/// scope.
-#[derive(Copy, Clone)]
+#[derive(Clone)]
enum NeverLoopResult {
/// A continue may occur for the main loop.
MayContinueMainLoop,
/// We have not encountered any main loop continue,
/// but we are diverging (subsequent control flow is not reachable)
- Diverging,
+ Diverging { break_spans: Vec<Span> },
/// We have not encountered any main loop continue,
/// and subsequent control flow is (possibly) reachable
Normal,
}
#[must_use]
-fn absorb_break(arg: NeverLoopResult) -> NeverLoopResult {
+fn absorb_break(arg: &NeverLoopResult) -> NeverLoopResult {
match arg {
- NeverLoopResult::Diverging | NeverLoopResult::Normal => NeverLoopResult::Normal,
+ NeverLoopResult::Diverging { .. } | NeverLoopResult::Normal => NeverLoopResult::Normal,
NeverLoopResult::MayContinueMainLoop => NeverLoopResult::MayContinueMainLoop,
}
}
@@ -94,7 +101,7 @@ fn absorb_break(arg: NeverLoopResult) -> NeverLoopResult {
#[must_use]
fn combine_seq(first: NeverLoopResult, second: impl FnOnce() -> NeverLoopResult) -> NeverLoopResult {
match first {
- NeverLoopResult::Diverging | NeverLoopResult::MayContinueMainLoop => first,
+ NeverLoopResult::Diverging { .. } | NeverLoopResult::MayContinueMainLoop => first,
NeverLoopResult::Normal => second(),
}
}
@@ -103,7 +110,7 @@ fn combine_seq(first: NeverLoopResult, second: impl FnOnce() -> NeverLoopResult)
#[must_use]
fn combine_seq_many(iter: impl IntoIterator<Item = NeverLoopResult>) -> NeverLoopResult {
for e in iter {
- if let NeverLoopResult::Diverging | NeverLoopResult::MayContinueMainLoop = e {
+ if let NeverLoopResult::Diverging { .. } | NeverLoopResult::MayContinueMainLoop = e {
return e;
}
}
@@ -118,7 +125,19 @@ fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult) -> NeverLoopResult
NeverLoopResult::MayContinueMainLoop
},
(NeverLoopResult::Normal, _) | (_, NeverLoopResult::Normal) => NeverLoopResult::Normal,
- (NeverLoopResult::Diverging, NeverLoopResult::Diverging) => NeverLoopResult::Diverging,
+ (
+ NeverLoopResult::Diverging {
+ break_spans: mut break_spans1,
+ },
+ NeverLoopResult::Diverging {
+ break_spans: mut break_spans2,
+ },
+ ) => {
+ break_spans1.append(&mut break_spans2);
+ NeverLoopResult::Diverging {
+ break_spans: break_spans1,
+ }
+ },
}
}
@@ -136,7 +155,7 @@ fn never_loop_block<'tcx>(
combine_seq_many(iter.map(|(e, els)| {
let e = never_loop_expr(cx, e, local_labels, main_loop_id);
// els is an else block in a let...else binding
- els.map_or(e, |els| {
+ els.map_or(e.clone(), |els| {
combine_seq(e, || match never_loop_block(cx, els, local_labels, main_loop_id) {
// Returning MayContinueMainLoop here means that
// we will not evaluate the rest of the body
@@ -144,7 +163,7 @@ fn never_loop_block<'tcx>(
// An else block always diverges, so the Normal case should not happen,
// but the analysis is approximate so it might return Normal anyway.
// Returning Normal here says that nothing more happens on the main path
- NeverLoopResult::Diverging | NeverLoopResult::Normal => NeverLoopResult::Normal,
+ NeverLoopResult::Diverging { .. } | NeverLoopResult::Normal => NeverLoopResult::Normal,
})
})
}))
@@ -159,6 +178,45 @@ fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'t
}
}
+fn stmt_source_span(stmt: &Stmt<'_>) -> Span {
+ let call_span = stmt.span.source_callsite();
+ // if it is a macro call, the span will be missing the trailing semicolon
+ if stmt.span == call_span {
+ return call_span;
+ }
+
+ // An expression without a trailing semi-colon (must have unit type).
+ if let StmtKind::Expr(..) = stmt.kind {
+ return call_span;
+ }
+
+ call_span.with_hi(call_span.hi() + BytePos(1))
+}
+
+/// Returns a Vec of all the individual spans after the highlighted expression in a block
+fn all_spans_after_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> Vec<Span> {
+ if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id) {
+ if let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id) {
+ return block
+ .stmts
+ .iter()
+ .skip_while(|inner| inner.hir_id != stmt.hir_id)
+ .map(stmt_source_span)
+ .chain(if let Some(e) = block.expr { vec![e.span] } else { vec![] })
+ .collect();
+ }
+
+ return vec![stmt.span];
+ }
+
+ vec![]
+}
+
+fn is_label_for_block(cx: &LateContext<'_>, dest: &Destination) -> bool {
+ dest.target_id
+ .is_ok_and(|hir_id| matches!(cx.tcx.hir_node(hir_id), Node::Block(_)))
+}
+
#[allow(clippy::too_many_lines)]
fn never_loop_expr<'tcx>(
cx: &LateContext<'tcx>,
@@ -197,7 +255,7 @@ fn never_loop_expr<'tcx>(
ExprKind::Loop(b, _, _, _) => {
// We don't attempt to track reachability after a loop,
// just assume there may have been a break somewhere
- absorb_break(never_loop_block(cx, b, local_labels, main_loop_id))
+ absorb_break(&never_loop_block(cx, b, local_labels, main_loop_id))
},
ExprKind::If(e, e2, e3) => {
let e1 = never_loop_expr(cx, e, local_labels, main_loop_id);
@@ -212,9 +270,10 @@ fn never_loop_expr<'tcx>(
ExprKind::Match(e, arms, _) => {
let e = never_loop_expr(cx, e, local_labels, main_loop_id);
combine_seq(e, || {
- arms.iter().fold(NeverLoopResult::Diverging, |a, b| {
- combine_branches(a, never_loop_expr(cx, b.body, local_labels, main_loop_id))
- })
+ arms.iter()
+ .fold(NeverLoopResult::Diverging { break_spans: vec![] }, |a, b| {
+ combine_branches(a, never_loop_expr(cx, b.body, local_labels, main_loop_id))
+ })
})
},
ExprKind::Block(b, _) => {
@@ -224,7 +283,7 @@ fn never_loop_expr<'tcx>(
let ret = never_loop_block(cx, b, local_labels, main_loop_id);
let jumped_to = b.targeted_by_break && local_labels.pop().unwrap().1;
match ret {
- NeverLoopResult::Diverging if jumped_to => NeverLoopResult::Normal,
+ NeverLoopResult::Diverging { .. } if jumped_to => NeverLoopResult::Normal,
_ => ret,
}
},
@@ -235,25 +294,39 @@ fn never_loop_expr<'tcx>(
if id == main_loop_id {
NeverLoopResult::MayContinueMainLoop
} else {
- NeverLoopResult::Diverging
+ NeverLoopResult::Diverging {
+ break_spans: all_spans_after_expr(cx, expr),
+ }
}
},
- ExprKind::Break(_, e) | ExprKind::Ret(e) => {
+ ExprKind::Ret(e) => {
let first = e.as_ref().map_or(NeverLoopResult::Normal, |e| {
never_loop_expr(cx, e, local_labels, main_loop_id)
});
combine_seq(first, || {
// checks if break targets a block instead of a loop
- if let ExprKind::Break(Destination { target_id: Ok(t), .. }, _) = expr.kind
- && let Some((_, reachable)) = local_labels.iter_mut().find(|(label, _)| *label == t)
- {
- *reachable = true;
+ mark_block_as_reachable(expr, local_labels);
+ NeverLoopResult::Diverging { break_spans: vec![] }
+ })
+ },
+ ExprKind::Break(dest, e) => {
+ let first = e.as_ref().map_or(NeverLoopResult::Normal, |e| {
+ never_loop_expr(cx, e, local_labels, main_loop_id)
+ });
+ combine_seq(first, || {
+ // checks if break targets a block instead of a loop
+ mark_block_as_reachable(expr, local_labels);
+ NeverLoopResult::Diverging {
+ break_spans: if is_label_for_block(cx, &dest) {
+ vec![]
+ } else {
+ all_spans_after_expr(cx, expr)
+ },
}
- NeverLoopResult::Diverging
})
},
ExprKind::Become(e) => combine_seq(never_loop_expr(cx, e, local_labels, main_loop_id), || {
- NeverLoopResult::Diverging
+ NeverLoopResult::Diverging { break_spans: vec![] }
}),
ExprKind::InlineAsm(asm) => combine_seq_many(asm.operands.iter().map(|(o, _)| match o {
InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
@@ -283,12 +356,12 @@ fn never_loop_expr<'tcx>(
};
let result = combine_seq(result, || {
if cx.typeck_results().expr_ty(expr).is_never() {
- NeverLoopResult::Diverging
+ NeverLoopResult::Diverging { break_spans: vec![] }
} else {
NeverLoopResult::Normal
}
});
- if let NeverLoopResult::Diverging = result
+ if let NeverLoopResult::Diverging { .. } = result
&& let Some(macro_call) = root_macro_call_first_node(cx, expr)
&& let Some(sym::todo_macro) = cx.tcx.get_diagnostic_name(macro_call.def_id)
{
@@ -316,3 +389,11 @@ fn for_to_if_let_sugg(cx: &LateContext<'_>, iterator: &Expr<'_>, pat: &Pat<'_>)
format!("if let Some({pat_snippet}) = {iter_snippet}.next()")
}
+
+fn mark_block_as_reachable(expr: &Expr<'_>, local_labels: &mut [(HirId, bool)]) {
+ if let ExprKind::Break(Destination { target_id: Ok(t), .. }, _) = expr.kind
+ && let Some((_, reachable)) = local_labels.iter_mut().find(|(label, _)| *label == t)
+ {
+ *reachable = true;
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index d1a54df..3aa449f 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -1,15 +1,15 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::source::snippet;
use hir::def::{DefKind, Res};
+use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_hir::{self as hir, AmbigArg};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::impl_lint_pass;
+use rustc_span::Span;
use rustc_span::edition::Edition;
-use rustc_span::{Span};
use std::collections::BTreeMap;
-use rustc_attr_data_structures::{AttributeKind, find_attr};
declare_clippy_lint! {
/// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/manual_abs_diff.rs b/src/tools/clippy/clippy_lints/src/manual_abs_diff.rs
index bac4b3d..288f27d 100644
--- a/src/tools/clippy/clippy_lints/src/manual_abs_diff.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_abs_diff.rs
@@ -5,7 +5,7 @@
use clippy_utils::source::HasSession as _;
use clippy_utils::sugg::Sugg;
use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{eq_expr_value, peel_blocks, span_contains_comment};
+use clippy_utils::{eq_expr_value, peel_blocks, peel_middle_ty_refs, span_contains_comment};
use rustc_errors::Applicability;
use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
@@ -62,7 +62,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
&& let ExprKind::Binary(op, rhs, lhs) = if_expr.cond.kind
&& let (BinOpKind::Gt | BinOpKind::Ge, mut a, mut b) | (BinOpKind::Lt | BinOpKind::Le, mut b, mut a) =
(op.node, rhs, lhs)
- && let Some(ty) = self.are_ty_eligible(cx, a, b)
+ && let Some((ty, b_n_refs)) = self.are_ty_eligible(cx, a, b)
&& is_sub_expr(cx, if_expr.then, a, b, ty)
&& is_sub_expr(cx, r#else, b, a, ty)
{
@@ -86,8 +86,9 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
}
};
let sugg = format!(
- "{}.abs_diff({})",
+ "{}.abs_diff({}{})",
Sugg::hir(cx, a, "..").maybe_paren(),
+ "*".repeat(b_n_refs),
Sugg::hir(cx, b, "..")
);
diag.span_suggestion(expr.span, "replace with `abs_diff`", sugg, applicability);
@@ -100,13 +101,15 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
impl ManualAbsDiff {
/// Returns a type if `a` and `b` are both of it, and this lint can be applied to that
/// type (currently, any primitive int, or a `Duration`)
- fn are_ty_eligible<'tcx>(&self, cx: &LateContext<'tcx>, a: &Expr<'_>, b: &Expr<'_>) -> Option<Ty<'tcx>> {
+ fn are_ty_eligible<'tcx>(&self, cx: &LateContext<'tcx>, a: &Expr<'_>, b: &Expr<'_>) -> Option<(Ty<'tcx>, usize)> {
let is_int = |ty: Ty<'_>| matches!(ty.kind(), ty::Uint(_) | ty::Int(_)) && self.msrv.meets(cx, msrvs::ABS_DIFF);
let is_duration =
|ty| is_type_diagnostic_item(cx, ty, sym::Duration) && self.msrv.meets(cx, msrvs::DURATION_ABS_DIFF);
let a_ty = cx.typeck_results().expr_ty(a).peel_refs();
- (a_ty == cx.typeck_results().expr_ty(b).peel_refs() && (is_int(a_ty) || is_duration(a_ty))).then_some(a_ty)
+ let (b_ty, b_n_refs) = peel_middle_ty_refs(cx.typeck_results().expr_ty(b));
+
+ (a_ty == b_ty && (is_int(a_ty) || is_duration(a_ty))).then_some((a_ty, b_n_refs))
}
}
diff --git a/src/tools/clippy/clippy_lints/src/manual_assert.rs b/src/tools/clippy/clippy_lints/src/manual_assert.rs
index 8378e15..ea6b01a 100644
--- a/src/tools/clippy/clippy_lints/src/manual_assert.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_assert.rs
@@ -60,7 +60,8 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
ExprKind::Unary(UnOp::Not, e) => (e, ""),
_ => (cond, "!"),
};
- let cond_sugg = sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_paren();
+ let cond_sugg =
+ sugg::Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "..", &mut applicability).maybe_paren();
let semicolon = if is_parent_stmt(cx, expr.hir_id) { ";" } else { "" };
let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip}){semicolon}");
// we show to the user the suggestion without the comments, but when applying the fix, include the
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 08c0caa..7e530e9 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -152,21 +152,26 @@ fn report_single_pattern(
}) if lit.node.is_str() || lit.node.is_bytestr() => pat_ref_count + 1,
_ => pat_ref_count,
};
- // References are only implicitly added to the pattern, so no overflow here.
- // e.g. will work: match &Some(_) { Some(_) => () }
- // will not: match Some(_) { &Some(_) => () }
- let ref_count_diff = ty_ref_count - pat_ref_count;
- // Try to remove address of expressions first.
- let (ex, removed) = peel_n_hir_expr_refs(ex, ref_count_diff);
- let ref_count_diff = ref_count_diff - removed;
+ // References are implicitly removed when `deref_patterns` are used.
+ // They are implicitly added when match ergonomics are used.
+ let (ex, ref_or_deref_adjust) = if ty_ref_count > pat_ref_count {
+ let ref_count_diff = ty_ref_count - pat_ref_count;
+
+ // Try to remove address of expressions first.
+ let (ex, removed) = peel_n_hir_expr_refs(ex, ref_count_diff);
+
+ (ex, String::from(if ref_count_diff == removed { "" } else { "&" }))
+ } else {
+ (ex, "*".repeat(pat_ref_count - ty_ref_count))
+ };
let msg = "you seem to be trying to use `match` for an equality check. Consider using `if`";
let sugg = format!(
"if {} == {}{} {}{els_str}",
snippet_with_context(cx, ex.span, ctxt, "..", &mut app).0,
// PartialEq for different reference counts may not exist.
- "&".repeat(ref_count_diff),
+ ref_or_deref_adjust,
snippet_with_applicability(cx, arm.pat.span, "..", &mut app),
expr_block(cx, arm.body, ctxt, "..", Some(expr.span), &mut app),
);
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
index 82e5a6d..6e5da5bd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
@@ -2,13 +2,15 @@
use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node};
use clippy_utils::source::snippet_with_applicability;
use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
+use clippy_utils::visitors::for_each_expr;
+use clippy_utils::{contains_return, is_inside_always_const_context, peel_blocks};
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
-use rustc_middle::ty;
use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
use std::borrow::Cow;
+use std::ops::ControlFlow;
use super::EXPECT_FUN_CALL;
@@ -23,10 +25,10 @@ pub(super) fn check<'tcx>(
receiver: &'tcx hir::Expr<'tcx>,
args: &'tcx [hir::Expr<'tcx>],
) {
- // Strip `&`, `as_ref()` and `as_str()` off `arg` until we're left with either a `String` or
+ // Strip `{}`, `&`, `as_ref()` and `as_str()` off `arg` until we're left with either a `String` or
// `&str`
fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
- let mut arg_root = arg;
+ let mut arg_root = peel_blocks(arg);
loop {
arg_root = match &arg_root.kind {
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => expr,
@@ -47,124 +49,68 @@ fn get_arg_root<'a>(cx: &LateContext<'_>, arg: &'a hir::Expr<'a>) -> &'a hir::Ex
arg_root
}
- // Only `&'static str` or `String` can be used directly in the `panic!`. Other types should be
- // converted to string.
- fn requires_to_string(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
- let arg_ty = cx.typeck_results().expr_ty(arg);
- if is_type_lang_item(cx, arg_ty, hir::LangItem::String) {
- return false;
+ fn contains_call<'a>(cx: &LateContext<'a>, arg: &'a hir::Expr<'a>) -> bool {
+ for_each_expr(cx, arg, |expr| {
+ if matches!(expr.kind, hir::ExprKind::MethodCall { .. } | hir::ExprKind::Call { .. })
+ && !is_inside_always_const_context(cx.tcx, expr.hir_id)
+ {
+ ControlFlow::Break(())
+ } else {
+ ControlFlow::Continue(())
+ }
+ })
+ .is_some()
+ }
+
+ if name == sym::expect
+ && let [arg] = args
+ && let arg_root = get_arg_root(cx, arg)
+ && contains_call(cx, arg_root)
+ && !contains_return(arg_root)
+ {
+ let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver);
+ let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym::Option) {
+ "||"
+ } else if is_type_diagnostic_item(cx, receiver_type, sym::Result) {
+ "|_|"
+ } else {
+ return;
+ };
+
+ let span_replace_word = method_span.with_hi(expr.span.hi());
+
+ let mut applicability = Applicability::MachineApplicable;
+
+ // Special handling for `format!` as arg_root
+ if let Some(macro_call) = root_macro_call_first_node(cx, arg_root) {
+ if cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
+ && let Some(format_args) = format_args_storage.get(cx, arg_root, macro_call.expn)
+ {
+ let span = format_args_inputs_span(format_args);
+ let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
+ span_lint_and_sugg(
+ cx,
+ EXPECT_FUN_CALL,
+ span_replace_word,
+ format!("function call inside of `{name}`"),
+ "try",
+ format!("unwrap_or_else({closure_args} panic!({sugg}))"),
+ applicability,
+ );
+ }
+ return;
}
- if let ty::Ref(_, ty, ..) = arg_ty.kind()
- && ty.is_str()
- && can_be_static_str(cx, arg)
- {
- return false;
- }
- true
+
+ let arg_root_snippet: Cow<'_, _> = snippet_with_applicability(cx, arg_root.span, "..", &mut applicability);
+
+ span_lint_and_sugg(
+ cx,
+ EXPECT_FUN_CALL,
+ span_replace_word,
+ format!("function call inside of `{name}`"),
+ "try",
+ format!("unwrap_or_else({closure_args} panic!(\"{{}}\", {arg_root_snippet}))"),
+ applicability,
+ );
}
-
- // Check if an expression could have type `&'static str`, knowing that it
- // has type `&str` for some lifetime.
- fn can_be_static_str(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
- match arg.kind {
- hir::ExprKind::Lit(_) => true,
- hir::ExprKind::Call(fun, _) => {
- if let hir::ExprKind::Path(ref p) = fun.kind {
- match cx.qpath_res(p, fun.hir_id) {
- hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!(
- cx.tcx.fn_sig(def_id).instantiate_identity().output().skip_binder().kind(),
- ty::Ref(re, ..) if re.is_static(),
- ),
- _ => false,
- }
- } else {
- false
- }
- },
- hir::ExprKind::MethodCall(..) => {
- cx.typeck_results()
- .type_dependent_def_id(arg.hir_id)
- .is_some_and(|method_id| {
- matches!(
- cx.tcx.fn_sig(method_id).instantiate_identity().output().skip_binder().kind(),
- ty::Ref(re, ..) if re.is_static()
- )
- })
- },
- hir::ExprKind::Path(ref p) => matches!(
- cx.qpath_res(p, arg.hir_id),
- hir::def::Res::Def(hir::def::DefKind::Const | hir::def::DefKind::Static { .. }, _)
- ),
- _ => false,
- }
- }
-
- fn is_call(node: &hir::ExprKind<'_>) -> bool {
- match node {
- hir::ExprKind::AddrOf(hir::BorrowKind::Ref, _, expr) => {
- is_call(&expr.kind)
- },
- hir::ExprKind::Call(..)
- | hir::ExprKind::MethodCall(..)
- // These variants are debatable or require further examination
- | hir::ExprKind::If(..)
- | hir::ExprKind::Match(..)
- | hir::ExprKind::Block{ .. } => true,
- _ => false,
- }
- }
-
- if args.len() != 1 || name != sym::expect || !is_call(&args[0].kind) {
- return;
- }
-
- let receiver_type = cx.typeck_results().expr_ty_adjusted(receiver);
- let closure_args = if is_type_diagnostic_item(cx, receiver_type, sym::Option) {
- "||"
- } else if is_type_diagnostic_item(cx, receiver_type, sym::Result) {
- "|_|"
- } else {
- return;
- };
-
- let arg_root = get_arg_root(cx, &args[0]);
-
- let span_replace_word = method_span.with_hi(expr.span.hi());
-
- let mut applicability = Applicability::MachineApplicable;
-
- // Special handling for `format!` as arg_root
- if let Some(macro_call) = root_macro_call_first_node(cx, arg_root) {
- if cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
- && let Some(format_args) = format_args_storage.get(cx, arg_root, macro_call.expn)
- {
- let span = format_args_inputs_span(format_args);
- let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
- span_lint_and_sugg(
- cx,
- EXPECT_FUN_CALL,
- span_replace_word,
- format!("function call inside of `{name}`"),
- "try",
- format!("unwrap_or_else({closure_args} panic!({sugg}))"),
- applicability,
- );
- }
- return;
- }
-
- let mut arg_root_snippet: Cow<'_, _> = snippet_with_applicability(cx, arg_root.span, "..", &mut applicability);
- if requires_to_string(cx, arg_root) {
- arg_root_snippet.to_mut().push_str(".to_string()");
- }
-
- span_lint_and_sugg(
- cx,
- EXPECT_FUN_CALL,
- span_replace_word,
- format!("function call inside of `{name}`"),
- "try",
- format!("unwrap_or_else({closure_args} {{ panic!(\"{{}}\", {arg_root_snippet}) }})"),
- applicability,
- );
}
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
index 9659938..94944bd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
@@ -1,6 +1,6 @@
use super::FILTER_MAP_BOOL_THEN;
use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::SpanRangeExt;
+use clippy_utils::source::{SpanRangeExt, snippet_with_context};
use clippy_utils::ty::is_copy;
use clippy_utils::{
CaptureKind, can_move_expr_to_closure, contains_return, is_from_proc_macro, is_trait_method, peel_blocks,
@@ -45,9 +45,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
.filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
.count()
&& let Some(param_snippet) = param.span.get_source_text(cx)
- && let Some(filter) = recv.span.get_source_text(cx)
- && let Some(map) = then_body.span.get_source_text(cx)
{
+ let mut applicability = Applicability::MachineApplicable;
+ let (filter, _) = snippet_with_context(cx, recv.span, expr.span.ctxt(), "..", &mut applicability);
+ let (map, _) = snippet_with_context(cx, then_body.span, expr.span.ctxt(), "..", &mut applicability);
+
span_lint_and_then(
cx,
FILTER_MAP_BOOL_THEN,
@@ -62,7 +64,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
"filter(|&{param_snippet}| {derefs}{filter}).map(|{param_snippet}| {map})",
derefs = "*".repeat(needed_derefs)
),
- Applicability::MachineApplicable,
+ applicability,
);
} else {
diag.help("consider using `filter` then `map` instead");
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
index 21f2ce8..bc96815 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
@@ -100,7 +100,6 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
match x {
UseKind::Return(s) => edits.push((s.with_leading_whitespace(cx).with_ctxt(s.ctxt()), String::new())),
UseKind::Borrowed(s) => {
- #[expect(clippy::range_plus_one)]
let range = s.map_range(cx, |_, src, range| {
let src = src.get(range.clone())?;
let trimmed = src.trim_start_matches([' ', '\t', '\n', '\r', '(']);
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index f2dabdd..bcd5455 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -3859,6 +3859,7 @@
declare_clippy_lint! {
/// ### What it does
/// Checks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where f is a function or closure that returns the `bool` type.
+ /// Also checks for equality comparisons like `option.map(f) == Some(true)` and `result.map(f) == Ok(true)`.
///
/// ### Why is this bad?
/// Readability. These can be written more concisely as `option.is_some_and(f)` and `result.is_ok_and(f)`.
@@ -3869,6 +3870,11 @@
/// # let result: Result<usize, ()> = Ok(1);
/// option.map(|a| a > 10).unwrap_or_default();
/// result.map(|a| a > 10).unwrap_or_default();
+ ///
+ /// option.map(|a| a > 10) == Some(true);
+ /// result.map(|a| a > 10) == Ok(true);
+ /// option.map(|a| a > 10) != Some(true);
+ /// result.map(|a| a > 10) != Ok(true);
/// ```
/// Use instead:
/// ```no_run
@@ -3876,11 +3882,16 @@
/// # let result: Result<usize, ()> = Ok(1);
/// option.is_some_and(|a| a > 10);
/// result.is_ok_and(|a| a > 10);
+ ///
+ /// option.is_some_and(|a| a > 10);
+ /// result.is_ok_and(|a| a > 10);
+ /// option.is_none_or(|a| a > 10);
+ /// !result.is_ok_and(|a| a > 10);
/// ```
#[clippy::version = "1.77.0"]
pub MANUAL_IS_VARIANT_AND,
pedantic,
- "using `.map(f).unwrap_or_default()`, which is more succinctly expressed as `is_some_and(f)` or `is_ok_and(f)`"
+ "using `.map(f).unwrap_or_default()` or `.map(f) == Some/Ok(true)`, which are more succinctly expressed as `is_some_and(f)` or `is_ok_and(f)`"
}
declare_clippy_lint! {
@@ -5275,10 +5286,6 @@ fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
}
map_identity::check(cx, expr, recv, m_arg, name, span);
manual_inspect::check(cx, expr, m_arg, name, span, self.msrv);
- crate::useless_conversion::check_function_application(cx, expr, recv, m_arg);
- },
- (sym::map_break | sym::map_continue, [m_arg]) => {
- crate::useless_conversion::check_function_application(cx, expr, recv, m_arg);
},
(sym::map_or, [def, map]) => {
option_map_or_none::check(cx, expr, recv, def, map);
@@ -5546,7 +5553,7 @@ fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
// Handle method calls whose receiver and arguments may come from expansion
if let ExprKind::MethodCall(path, recv, args, _call_span) = expr.kind {
match (path.ident.name, args) {
- (sym::expect, [_]) if !matches!(method_call(recv), Some((sym::ok | sym::err, _, [], _, _))) => {
+ (sym::expect, [_]) => {
unwrap_expect_used::check(
cx,
expr,
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index 6ce7dd3..04f0e3c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -242,15 +242,23 @@ fn check_or_fn_call<'tcx>(
let inner_arg = peel_blocks(arg);
for_each_expr(cx, inner_arg, |ex| {
let is_top_most_expr = ex.hir_id == inner_arg.hir_id;
- if let hir::ExprKind::Call(fun, fun_args) = ex.kind {
- let fun_span = if fun_args.is_empty() && is_top_most_expr {
- Some(fun.span)
- } else {
- None
- };
- if check_or_fn_call(cx, name, method_span, receiver, arg, Some(lambda), expr.span, fun_span) {
- return ControlFlow::Break(());
- }
+ match ex.kind {
+ hir::ExprKind::Call(fun, fun_args) => {
+ let fun_span = if fun_args.is_empty() && is_top_most_expr {
+ Some(fun.span)
+ } else {
+ None
+ };
+ if check_or_fn_call(cx, name, method_span, receiver, arg, Some(lambda), expr.span, fun_span) {
+ return ControlFlow::Break(());
+ }
+ },
+ hir::ExprKind::MethodCall(..) => {
+ if check_or_fn_call(cx, name, method_span, receiver, arg, Some(lambda), expr.span, None) {
+ return ControlFlow::Break(());
+ }
+ },
+ _ => {},
}
ControlFlow::Continue(())
});
diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
index 760ecf0..18e2b38 100644
--- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
@@ -7,9 +7,7 @@
use rustc_ast::LitKind;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::{
- Block, Expr, ExprKind, Impl, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData,
-};
+use rustc_hir::{Block, Expr, ExprKind, Impl, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{Ty, TypeckResults};
use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index c4a3d10..5a50259 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint;
use rustc_attr_data_structures::{AttributeKind, find_attr};
-use rustc_hir as hir;
-use rustc_hir::Attribute;
+use rustc_hir::def_id::DefId;
+use rustc_hir::{self as hir, Attribute};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::AssocItemContainer;
use rustc_session::declare_lint_pass;
@@ -97,11 +97,23 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
}
match it.kind {
hir::ItemKind::Fn { .. } => {
+ if fn_is_externally_exported(cx, it.owner_id.to_def_id()) {
+ return;
+ }
+
let desc = "a function";
let attrs = cx.tcx.hir_attrs(it.hir_id());
check_missing_inline_attrs(cx, attrs, it.span, desc);
},
- hir::ItemKind::Trait(ref _constness, ref _is_auto, ref _unsafe, _ident, _generics, _bounds, trait_items) => {
+ hir::ItemKind::Trait(
+ ref _constness,
+ ref _is_auto,
+ ref _unsafe,
+ _ident,
+ _generics,
+ _bounds,
+ trait_items,
+ ) => {
// note: we need to check if the trait is exported so we can't use
// `LateLintPass::check_trait_item` here.
for &tit in trait_items {
@@ -173,3 +185,10 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::Impl
check_missing_inline_attrs(cx, attrs, impl_item.span, desc);
}
}
+
+/// Checks if this function is externally exported, where #[inline] wouldn't have the desired effect
+/// and a rustc warning would be triggered, see #15301
+fn fn_is_externally_exported(cx: &LateContext<'_>, def_id: DefId) -> bool {
+ let attrs = cx.tcx.codegen_fn_attrs(def_id);
+ attrs.contains_extern_indicator()
+}
diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
index fa61d0f..399bf4e 100644
--- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
@@ -66,7 +66,9 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
}) = item.kind
&& let Some(trait_id) = trait_ref.trait_def_id()
{
- let trait_item_ids: DefIdSet = cx.tcx.associated_items(item.owner_id)
+ let trait_item_ids: DefIdSet = cx
+ .tcx
+ .associated_items(item.owner_id)
.in_definition_order()
.filter_map(|assoc_item| assoc_item.trait_item_def_id)
.collect();
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index d9f4fb2..a489c0a 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -171,14 +171,11 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => self.report_diverging_sub_expr(e),
ExprKind::Call(func, _) => {
let typ = self.cx.typeck_results().expr_ty(func);
- match typ.kind() {
- ty::FnDef(..) | ty::FnPtr(..) => {
- let sig = typ.fn_sig(self.cx.tcx);
- if self.cx.tcx.instantiate_bound_regions_with_erased(sig).output().kind() == &ty::Never {
- self.report_diverging_sub_expr(e);
- }
- },
- _ => {},
+ if typ.is_fn() {
+ let sig = typ.fn_sig(self.cx.tcx);
+ if self.cx.tcx.instantiate_bound_regions_with_erased(sig).output().kind() == &ty::Never {
+ self.report_diverging_sub_expr(e);
+ }
}
},
ExprKind::MethodCall(..) => {
diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs
index 2f1ab3d..31f51b4 100644
--- a/src/tools/clippy/clippy_lints/src/mut_reference.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs
@@ -79,7 +79,7 @@ fn check_arguments<'tcx>(
name: &str,
fn_kind: &str,
) {
- if let ty::FnDef(..) | ty::FnPtr(..) = type_definition.kind() {
+ if type_definition.is_fn() {
let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
for (argument, parameter) in iter::zip(arguments, parameters) {
if let ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not) = parameter.kind()
diff --git a/src/tools/clippy/clippy_lints/src/needless_for_each.rs b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
index 6a7c843..a67545e 100644
--- a/src/tools/clippy/clippy_lints/src/needless_for_each.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
@@ -6,7 +6,7 @@
use rustc_span::Span;
use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
use clippy_utils::ty::has_iter_method;
use clippy_utils::{is_trait_method, sym};
@@ -101,18 +101,23 @@ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
let body_param_sugg = snippet_with_applicability(cx, body.params[0].pat.span, "..", &mut applicability);
let for_each_rev_sugg = snippet_with_applicability(cx, for_each_recv.span, "..", &mut applicability);
- let body_value_sugg = snippet_with_applicability(cx, body.value.span, "..", &mut applicability);
+ let (body_value_sugg, is_macro_call) =
+ snippet_with_context(cx, body.value.span, for_each_recv.span.ctxt(), "..", &mut applicability);
let sugg = format!(
"for {} in {} {}",
body_param_sugg,
for_each_rev_sugg,
- match body.value.kind {
- ExprKind::Block(block, _) if is_let_desugar(block) => {
- format!("{{ {body_value_sugg} }}")
- },
- ExprKind::Block(_, _) => body_value_sugg.to_string(),
- _ => format!("{{ {body_value_sugg}; }}"),
+ if is_macro_call {
+ format!("{{ {body_value_sugg}; }}")
+ } else {
+ match body.value.kind {
+ ExprKind::Block(block, _) if is_let_desugar(block) => {
+ format!("{{ {body_value_sugg} }}")
+ },
+ ExprKind::Block(_, _) => body_value_sugg.to_string(),
+ _ => format!("{{ {body_value_sugg}; }}"),
+ }
}
);
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index c97ecce..2006a82 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -246,8 +246,10 @@ fn check_fn(
for (span, suggestion) in clone_spans {
diag.span_suggestion(
span,
- span.get_source_text(cx)
- .map_or("change the call to".to_owned(), |src| format!("change `{src}` to")),
+ span.get_source_text(cx).map_or_else(
+ || "change the call to".to_owned(),
+ |src| format!("change `{src}` to"),
+ ),
suggestion,
Applicability::Unspecified,
);
@@ -275,8 +277,10 @@ fn check_fn(
for (span, suggestion) in clone_spans {
diag.span_suggestion(
span,
- span.get_source_text(cx)
- .map_or("change the call to".to_owned(), |src| format!("change `{src}` to")),
+ span.get_source_text(cx).map_or_else(
+ || "change the call to".to_owned(),
+ |src| format!("change `{src}` to"),
+ ),
suggestion,
Applicability::Unspecified,
);
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index 3b86f1d..b598a39 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -65,11 +65,16 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
..
}) = item.kind
{
- for assoc_item in cx.tcx.associated_items(item.owner_id.def_id)
+ for assoc_item in cx
+ .tcx
+ .associated_items(item.owner_id.def_id)
.filter_by_name_unhygienic(sym::new)
{
if let AssocKind::Fn { has_self: false, .. } = assoc_item.kind {
- let impl_item = cx.tcx.hir_node_by_def_id(assoc_item.def_id.expect_local()).expect_impl_item();
+ let impl_item = cx
+ .tcx
+ .hir_node_by_def_id(assoc_item.def_id.expect_local())
+ .expect_impl_item();
if impl_item.span.in_external_macro(cx.sess().source_map()) {
return;
}
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index a78a342..466beb0 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -3,12 +3,11 @@
use clippy_utils::consts::{ConstEvalCtxt, Constant};
use clippy_utils::diagnostics::span_lint;
use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary};
+use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary, sym};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{self, Ty};
use rustc_session::impl_lint_pass;
-use rustc_span::symbol::sym;
use rustc_span::{Span, Symbol};
use {rustc_ast as ast, rustc_hir as hir};
@@ -89,6 +88,18 @@ fn has_allowed_unary(&self, ty: Ty<'_>) -> bool {
self.allowed_unary.contains(ty_string_elem)
}
+ fn is_non_zero_u(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
+ if let ty::Adt(adt, substs) = ty.kind()
+ && cx.tcx.is_diagnostic_item(sym::NonZero, adt.did())
+ && let int_type = substs.type_at(0)
+ && matches!(int_type.kind(), ty::Uint(_))
+ {
+ true
+ } else {
+ false
+ }
+ }
+
/// Verifies built-in types that have specific allowed operations
fn has_specific_allowed_type_and_operation<'tcx>(
cx: &LateContext<'tcx>,
@@ -97,33 +108,12 @@ fn has_specific_allowed_type_and_operation<'tcx>(
rhs_ty: Ty<'tcx>,
) -> bool {
let is_div_or_rem = matches!(op, hir::BinOpKind::Div | hir::BinOpKind::Rem);
- let is_non_zero_u = |cx: &LateContext<'tcx>, ty: Ty<'tcx>| {
- let tcx = cx.tcx;
-
- let ty::Adt(adt, substs) = ty.kind() else { return false };
-
- if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
- return false;
- }
-
- let int_type = substs.type_at(0);
- let unsigned_int_types = [
- tcx.types.u8,
- tcx.types.u16,
- tcx.types.u32,
- tcx.types.u64,
- tcx.types.u128,
- tcx.types.usize,
- ];
-
- unsigned_int_types.contains(&int_type)
- };
let is_sat_or_wrap = |ty: Ty<'_>| {
is_type_diagnostic_item(cx, ty, sym::Saturating) || is_type_diagnostic_item(cx, ty, sym::Wrapping)
};
// If the RHS is `NonZero<u*>`, then division or module by zero will never occur.
- if is_non_zero_u(cx, rhs_ty) && is_div_or_rem {
+ if Self::is_non_zero_u(cx, rhs_ty) && is_div_or_rem {
return true;
}
@@ -219,6 +209,18 @@ fn manage_bin_ops<'tcx>(
let (mut actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs);
actual_lhs = expr_or_init(cx, actual_lhs);
actual_rhs = expr_or_init(cx, actual_rhs);
+
+ // `NonZeroU*.get() - 1`, will never overflow
+ if let hir::BinOpKind::Sub = op
+ && let hir::ExprKind::MethodCall(method, receiver, [], _) = actual_lhs.kind
+ && method.ident.name == sym::get
+ && let receiver_ty = cx.typeck_results().expr_ty(receiver).peel_refs()
+ && Self::is_non_zero_u(cx, receiver_ty)
+ && let Some(1) = Self::literal_integer(cx, actual_rhs)
+ {
+ return;
+ }
+
let lhs_ty = cx.typeck_results().expr_ty(actual_lhs).peel_refs();
let rhs_ty = cx.typeck_results().expr_ty_adjusted(actual_rhs).peel_refs();
if self.has_allowed_binary(lhs_ty, rhs_ty) {
@@ -227,6 +229,7 @@ fn manage_bin_ops<'tcx>(
if Self::has_specific_allowed_type_and_operation(cx, lhs_ty, op, rhs_ty) {
return;
}
+
let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) {
if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op {
// At least for integers, shifts are already handled by the CTFE
diff --git a/src/tools/clippy/clippy_lints/src/operators/manual_is_multiple_of.rs b/src/tools/clippy/clippy_lints/src/operators/manual_is_multiple_of.rs
index 821178a..55bb78c 100644
--- a/src/tools/clippy/clippy_lints/src/operators/manual_is_multiple_of.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/manual_is_multiple_of.rs
@@ -2,11 +2,12 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::sugg::Sugg;
+use clippy_utils::ty::expr_type_is_certain;
use rustc_ast::BinOpKind;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::LateContext;
-use rustc_middle::ty;
+use rustc_middle::ty::{self, Ty};
use super::MANUAL_IS_MULTIPLE_OF;
@@ -22,9 +23,21 @@ pub(super) fn check<'tcx>(
&& let Some(operand) = uint_compare_to_zero(cx, op, lhs, rhs)
&& let ExprKind::Binary(operand_op, operand_left, operand_right) = operand.kind
&& operand_op.node == BinOpKind::Rem
+ && matches!(
+ cx.typeck_results().expr_ty_adjusted(operand_left).peel_refs().kind(),
+ ty::Uint(_)
+ )
+ && matches!(
+ cx.typeck_results().expr_ty_adjusted(operand_right).peel_refs().kind(),
+ ty::Uint(_)
+ )
+ && expr_type_is_certain(cx, operand_left)
{
let mut app = Applicability::MachineApplicable;
- let divisor = Sugg::hir_with_applicability(cx, operand_right, "_", &mut app);
+ let divisor = deref_sugg(
+ Sugg::hir_with_applicability(cx, operand_right, "_", &mut app),
+ cx.typeck_results().expr_ty_adjusted(operand_right),
+ );
span_lint_and_sugg(
cx,
MANUAL_IS_MULTIPLE_OF,
@@ -64,3 +77,11 @@ fn uint_compare_to_zero<'tcx>(
matches!(cx.typeck_results().expr_ty_adjusted(operand).kind(), ty::Uint(_)).then_some(operand)
}
+
+fn deref_sugg<'a>(sugg: Sugg<'a>, ty: Ty<'_>) -> Sugg<'a> {
+ if let ty::Ref(_, target_ty, _) = ty.kind() {
+ deref_sugg(sugg.deref(), *target_ty)
+ } else {
+ sugg
+ }
+}
diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
index 19d9acf..4197680 100644
--- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
@@ -96,6 +96,12 @@ fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let ExprKind::Match(_, arms, _) = expr.kind {
+ // if the match is generated by an external macro, the writer does not control
+ // how the scrutinee (`match &scrutiny { ... }`) is matched
+ if expr.span.in_external_macro(cx.sess().source_map()) {
+ return;
+ }
+
for arm in arms {
let pat = &arm.pat;
if apply_lint(cx, pat, DerefPossible::Possible) {
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 94cdcf0..b3058c5 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -584,7 +584,13 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
Some((Node::Stmt(_), _)) => (),
Some((Node::LetStmt(l), _)) => {
// Only trace simple bindings. e.g `let x = y;`
- if let PatKind::Binding(BindingMode::NONE, id, _, None) = l.pat.kind {
+ if let PatKind::Binding(BindingMode::NONE, id, ident, None) = l.pat.kind
+ // Let's not lint for the current parameter. The user may still intend to mutate
+ // (or, if not mutate, then perhaps call a method that's not otherwise available
+ // for) the referenced value behind the parameter through this local let binding
+ // with the underscore being only temporary.
+ && !ident.name.as_str().starts_with('_')
+ {
self.bindings.insert(id, args_idx);
} else {
set_skip_flag();
@@ -650,7 +656,14 @@ fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
.filter_map(|(i, arg)| {
let param = &body.params[arg.idx];
match param.pat.kind {
- PatKind::Binding(BindingMode::NONE, id, _, None) if !is_lint_allowed(cx, PTR_ARG, param.hir_id) => {
+ PatKind::Binding(BindingMode::NONE, id, ident, None)
+ if !is_lint_allowed(cx, PTR_ARG, param.hir_id)
+ // Let's not lint for the current parameter. The user may still intend to mutate
+ // (or, if not mutate, then perhaps call a method that's not otherwise available
+ // for) the referenced value behind the parameter with the underscore being only
+ // temporary.
+ && !ident.name.as_str().starts_with('_') =>
+ {
Some((id, i))
},
_ => {
diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs
index d292ed8..9281678 100644
--- a/src/tools/clippy/clippy_lints/src/ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/ranges.rs
@@ -4,15 +4,20 @@
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
-use clippy_utils::{get_parent_expr, higher, is_in_const_context, is_integer_const, path_to_local};
+use clippy_utils::ty::implements_trait;
+use clippy_utils::{
+ expr_use_ctxt, fn_def_id, get_parent_expr, higher, is_in_const_context, is_integer_const, is_path_lang_item,
+ path_to_local,
+};
+use rustc_ast::Mutability;
use rustc_ast::ast::RangeLimits;
use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind, HirId};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
+use rustc_hir::{BinOpKind, Expr, ExprKind, HirId, LangItem, Node};
+use rustc_lint::{LateContext, LateLintPass, Lint};
+use rustc_middle::ty::{self, ClauseKind, GenericArgKind, PredicatePolarity, Ty};
use rustc_session::impl_lint_pass;
-use rustc_span::Span;
use rustc_span::source_map::Spanned;
+use rustc_span::{Span, sym};
use std::cmp::Ordering;
declare_clippy_lint! {
@@ -24,6 +29,12 @@
/// The code is more readable with an inclusive range
/// like `x..=y`.
///
+ /// ### Limitations
+ /// The lint is conservative and will trigger only when switching
+ /// from an exclusive to an inclusive range is provably safe from
+ /// a typing point of view. This corresponds to situations where
+ /// the range is used as an iterator, or for indexing.
+ ///
/// ### Known problems
/// Will add unnecessary pair of parentheses when the
/// expression is not wrapped in a pair but starts with an opening parenthesis
@@ -34,11 +45,6 @@
/// exclusive ranges, because they essentially add an extra branch that
/// LLVM may fail to hoist out of the loop.
///
- /// This will cause a warning that cannot be fixed if the consumer of the
- /// range only accepts a specific range type, instead of the generic
- /// `RangeBounds` trait
- /// ([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)).
- ///
/// ### Example
/// ```no_run
/// # let x = 0;
@@ -71,11 +77,11 @@
/// The code is more readable with an exclusive range
/// like `x..y`.
///
- /// ### Known problems
- /// This will cause a warning that cannot be fixed if
- /// the consumer of the range only accepts a specific range type, instead of
- /// the generic `RangeBounds` trait
- /// ([#3307](https://github.com/rust-lang/rust-clippy/issues/3307)).
+ /// ### Limitations
+ /// The lint is conservative and will trigger only when switching
+ /// from an inclusive to an exclusive range is provably safe from
+ /// a typing point of view. This corresponds to situations where
+ /// the range is used as an iterator, or for indexing.
///
/// ### Example
/// ```no_run
@@ -344,70 +350,188 @@ fn check_range_bounds<'a, 'tcx>(cx: &'a LateContext<'tcx>, ex: &'a Expr<'_>) ->
None
}
-// exclusive range plus one: `x..(y+1)`
-fn check_exclusive_range_plus_one(cx: &LateContext<'_>, expr: &Expr<'_>) {
- if expr.span.can_be_used_for_suggestions()
- && let Some(higher::Range {
- start,
- end: Some(end),
- limits: RangeLimits::HalfOpen,
- }) = higher::Range::hir(expr)
- && let Some(y) = y_plus_one(cx, end)
+/// Check whether `expr` could switch range types without breaking the typing requirements. This is
+/// generally the case when `expr` is used as an iterator for example, or as a slice or `&str`
+/// index.
+///
+/// FIXME: Note that the current implementation may still return false positives. A proper fix would
+/// check that the obligations are still satisfied after switching the range type.
+fn can_switch_ranges<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ original: RangeLimits,
+ inner_ty: Ty<'tcx>,
+) -> bool {
+ let use_ctxt = expr_use_ctxt(cx, expr);
+ let (Node::Expr(parent_expr), false) = (use_ctxt.node, use_ctxt.is_ty_unified) else {
+ return false;
+ };
+
+ // Check if `expr` is the argument of a compiler-generated `IntoIter::into_iter(expr)`
+ if let ExprKind::Call(func, [arg]) = parent_expr.kind
+ && arg.hir_id == use_ctxt.child_id
+ && is_path_lang_item(cx, func, LangItem::IntoIterIntoIter)
{
- let span = expr.span;
- span_lint_and_then(
- cx,
- RANGE_PLUS_ONE,
- span,
- "an inclusive range would be more readable",
- |diag| {
- let start = start.map_or(String::new(), |x| Sugg::hir(cx, x, "x").maybe_paren().to_string());
- let end = Sugg::hir(cx, y, "y").maybe_paren();
- match span.with_source_text(cx, |src| src.starts_with('(') && src.ends_with(')')) {
- Some(true) => {
- diag.span_suggestion(span, "use", format!("({start}..={end})"), Applicability::MaybeIncorrect);
- },
- Some(false) => {
- diag.span_suggestion(
- span,
- "use",
- format!("{start}..={end}"),
- Applicability::MachineApplicable, // snippet
- );
- },
- None => {},
- }
- },
- );
+ return true;
}
+
+ // Check if `expr` is used as the receiver of a method of the `Iterator`, `IntoIterator`,
+ // or `RangeBounds` traits.
+ if let ExprKind::MethodCall(_, receiver, _, _) = parent_expr.kind
+ && receiver.hir_id == use_ctxt.child_id
+ && let Some(method_did) = cx.typeck_results().type_dependent_def_id(parent_expr.hir_id)
+ && let Some(trait_did) = cx.tcx.trait_of_item(method_did)
+ && matches!(
+ cx.tcx.get_diagnostic_name(trait_did),
+ Some(sym::Iterator | sym::IntoIterator | sym::RangeBounds)
+ )
+ {
+ return true;
+ }
+
+ // Check if `expr` is an argument of a call which requires an `Iterator`, `IntoIterator`,
+ // or `RangeBounds` trait.
+ if let ExprKind::Call(_, args) | ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
+ && let Some(id) = fn_def_id(cx, parent_expr)
+ && let Some(arg_idx) = args.iter().position(|e| e.hir_id == use_ctxt.child_id)
+ {
+ let input_idx = if matches!(parent_expr.kind, ExprKind::MethodCall(..)) {
+ arg_idx + 1
+ } else {
+ arg_idx
+ };
+ let inputs = cx
+ .tcx
+ .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity())
+ .inputs();
+ let expr_ty = inputs[input_idx];
+ // Check that the `expr` type is present only once, otherwise modifying just one of them might be
+ // risky if they are referenced using the same generic type for example.
+ if inputs.iter().enumerate().all(|(n, ty)|
+ n == input_idx
+ || !ty.walk().any(|arg| matches!(arg.kind(),
+ GenericArgKind::Type(ty) if ty == expr_ty)))
+ // Look for a clause requiring `Iterator`, `IntoIterator`, or `RangeBounds`, and resolving to `expr_type`.
+ && cx
+ .tcx
+ .param_env(id)
+ .caller_bounds()
+ .into_iter()
+ .any(|p| {
+ if let ClauseKind::Trait(t) = p.kind().skip_binder()
+ && t.polarity == PredicatePolarity::Positive
+ && matches!(
+ cx.tcx.get_diagnostic_name(t.trait_ref.def_id),
+ Some(sym::Iterator | sym::IntoIterator | sym::RangeBounds)
+ )
+ {
+ t.self_ty() == expr_ty
+ } else {
+ false
+ }
+ })
+ {
+ return true;
+ }
+ }
+
+ // Check if `expr` is used for indexing, and if the switched range type could be used
+ // as well.
+ if let ExprKind::Index(outer_expr, index, _) = parent_expr.kind
+ && index.hir_id == expr.hir_id
+ // Build the switched range type (for example `RangeInclusive<usize>`).
+ && let Some(switched_range_def_id) = match original {
+ RangeLimits::HalfOpen => cx.tcx.lang_items().range_inclusive_struct(),
+ RangeLimits::Closed => cx.tcx.lang_items().range_struct(),
+ }
+ && let switched_range_ty = cx
+ .tcx
+ .type_of(switched_range_def_id)
+ .instantiate(cx.tcx, &[inner_ty.into()])
+ // Check that the switched range type can be used for indexing the original expression
+ // through the `Index` or `IndexMut` trait.
+ && let ty::Ref(_, outer_ty, mutability) = cx.typeck_results().expr_ty_adjusted(outer_expr).kind()
+ && let Some(index_def_id) = match mutability {
+ Mutability::Not => cx.tcx.lang_items().index_trait(),
+ Mutability::Mut => cx.tcx.lang_items().index_mut_trait(),
+ }
+ && implements_trait(cx, *outer_ty, index_def_id, &[switched_range_ty.into()])
+ // We could also check that the associated item of the `index_def_id` trait with the switched range type
+ // return the same type, but it is reasonable to expect so. We can't check that the result is identical
+ // in both `Index<Range<…>>` and `Index<RangeInclusive<…>>` anyway.
+ {
+ return true;
+ }
+
+ false
+}
+
+// exclusive range plus one: `x..(y+1)`
+fn check_exclusive_range_plus_one<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+ check_range_switch(
+ cx,
+ expr,
+ RangeLimits::HalfOpen,
+ y_plus_one,
+ RANGE_PLUS_ONE,
+ "an inclusive range would be more readable",
+ "..=",
+ );
}
// inclusive range minus one: `x..=(y-1)`
-fn check_inclusive_range_minus_one(cx: &LateContext<'_>, expr: &Expr<'_>) {
+fn check_inclusive_range_minus_one<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+ check_range_switch(
+ cx,
+ expr,
+ RangeLimits::Closed,
+ y_minus_one,
+ RANGE_MINUS_ONE,
+ "an exclusive range would be more readable",
+ "..",
+ );
+}
+
+/// Check for a `kind` of range in `expr`, check for `predicate` on the end,
+/// and emit the `lint` with `msg` and the `operator`.
+fn check_range_switch<'tcx>(
+ cx: &LateContext<'tcx>,
+ expr: &'tcx Expr<'_>,
+ kind: RangeLimits,
+ predicate: impl for<'hir> FnOnce(&LateContext<'_>, &Expr<'hir>) -> Option<&'hir Expr<'hir>>,
+ lint: &'static Lint,
+ msg: &'static str,
+ operator: &str,
+) {
if expr.span.can_be_used_for_suggestions()
&& let Some(higher::Range {
start,
end: Some(end),
- limits: RangeLimits::Closed,
+ limits,
}) = higher::Range::hir(expr)
- && let Some(y) = y_minus_one(cx, end)
+ && limits == kind
+ && let Some(y) = predicate(cx, end)
+ && can_switch_ranges(cx, expr, kind, cx.typeck_results().expr_ty(y))
{
- span_lint_and_then(
- cx,
- RANGE_MINUS_ONE,
- expr.span,
- "an exclusive range would be more readable",
- |diag| {
- let start = start.map_or(String::new(), |x| Sugg::hir(cx, x, "x").maybe_paren().to_string());
- let end = Sugg::hir(cx, y, "y").maybe_paren();
- diag.span_suggestion(
- expr.span,
- "use",
- format!("{start}..{end}"),
- Applicability::MachineApplicable, // snippet
- );
- },
- );
+ let span = expr.span;
+ span_lint_and_then(cx, lint, span, msg, |diag| {
+ let mut app = Applicability::MachineApplicable;
+ let start = start.map_or(String::new(), |x| {
+ Sugg::hir_with_applicability(cx, x, "<x>", &mut app)
+ .maybe_paren()
+ .to_string()
+ });
+ let end = Sugg::hir_with_applicability(cx, y, "<y>", &mut app).maybe_paren();
+ match span.with_source_text(cx, |src| src.starts_with('(') && src.ends_with(')')) {
+ Some(true) => {
+ diag.span_suggestion(span, "use", format!("({start}{operator}{end})"), app);
+ },
+ Some(false) => {
+ diag.span_suggestion(span, "use", format!("{start}{operator}{end}"), app);
+ },
+ None => {},
+ }
+ });
}
}
@@ -494,7 +618,7 @@ fn is_empty_range(limits: RangeLimits, ordering: Ordering) -> bool {
}
}
-fn y_plus_one<'t>(cx: &LateContext<'_>, expr: &'t Expr<'_>) -> Option<&'t Expr<'t>> {
+fn y_plus_one<'tcx>(cx: &LateContext<'_>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
match expr.kind {
ExprKind::Binary(
Spanned {
@@ -515,7 +639,7 @@ fn y_plus_one<'t>(cx: &LateContext<'_>, expr: &'t Expr<'_>) -> Option<&'t Expr<'
}
}
-fn y_minus_one<'t>(cx: &LateContext<'_>, expr: &'t Expr<'_>) -> Option<&'t Expr<'t>> {
+fn y_minus_one<'tcx>(cx: &LateContext<'_>, expr: &Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
match expr.kind {
ExprKind::Binary(
Spanned {
diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs
index 85fde78..67eb71f 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -3,7 +3,7 @@
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind};
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{AssocKind, AssocItem};
+use rustc_middle::ty::{AssocItem, AssocKind};
use rustc_session::declare_lint_pass;
use rustc_span::Span;
use rustc_span::symbol::Symbol;
@@ -53,11 +53,7 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
for id in cx.tcx.hir_free_items() {
if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. })
&& let item = cx.tcx.hir_item(id)
- && let ItemKind::Impl(Impl {
- of_trait,
- self_ty,
- ..
- }) = &item.kind
+ && let ItemKind::Impl(Impl { of_trait, self_ty, .. }) = &item.kind
&& let TyKind::Path(QPath::Resolved(_, Path { res, .. })) = self_ty.kind
{
if !map.contains_key(res) {
@@ -127,7 +123,9 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
},
None => {
for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() {
- let AssocKind::Fn { name, .. } = assoc_item.kind else { continue };
+ let AssocKind::Fn { name, .. } = assoc_item.kind else {
+ continue;
+ };
let impl_span = cx.tcx.def_span(assoc_item.def_id);
let hir_id = cx.tcx.local_def_id_to_hir_id(assoc_item.def_id.expect_local());
if let Some(trait_spans) = existing_name.trait_methods.get(&name) {
@@ -140,10 +138,7 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
|diag| {
// TODO should we `span_note` on every trait?
// iterate on trait_spans?
- diag.span_note(
- trait_spans[0],
- format!("existing `{name}` defined here"),
- );
+ diag.span_note(trait_spans[0], format!("existing `{name}` defined here"));
},
);
}
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index e67afc7..5a3e4b7 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -1,8 +1,12 @@
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::is_def_id_trait_method;
+use clippy_utils::usage::is_todo_unimplemented_stub;
use rustc_hir::def::DefKind;
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};
-use rustc_hir::{Body, Defaultness, Expr, ExprKind, FnDecl, HirId, Node, TraitItem, YieldSource};
+use rustc_hir::{
+ Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, Defaultness, Expr, ExprKind, FnDecl, HirId, Node,
+ TraitItem, YieldSource,
+};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_session::impl_lint_pass;
@@ -81,11 +85,8 @@ fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
let is_async_block = matches!(
ex.kind,
- ExprKind::Closure(rustc_hir::Closure {
- kind: rustc_hir::ClosureKind::Coroutine(rustc_hir::CoroutineKind::Desugared(
- rustc_hir::CoroutineDesugaring::Async,
- _
- )),
+ ExprKind::Closure(Closure {
+ kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)),
..
})
);
@@ -120,6 +121,7 @@ fn check_fn(
&& fn_kind.asyncness().is_async()
&& !is_def_id_trait_method(cx, def_id)
&& !is_default_trait_impl(cx, def_id)
+ && !async_fn_contains_todo_unimplemented_macro(cx, body)
{
let mut visitor = AsyncFnVisitor {
cx,
@@ -203,3 +205,18 @@ fn is_default_trait_impl(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
})
)
}
+
+fn async_fn_contains_todo_unimplemented_macro(cx: &LateContext<'_>, body: &Body<'_>) -> bool {
+ if let ExprKind::Closure(closure) = body.value.kind
+ && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) = closure.kind
+ && let body = cx.tcx.hir_body(closure.body)
+ && let ExprKind::Block(block, _) = body.value.kind
+ && block.stmts.is_empty()
+ && let Some(expr) = block.expr
+ && let ExprKind::DropTemps(inner) = expr.kind
+ {
+ return is_todo_unimplemented_stub(cx, inner);
+ }
+
+ false
+}
diff --git a/src/tools/clippy/clippy_lints/src/unused_self.rs b/src/tools/clippy/clippy_lints/src/unused_self.rs
index 12da891..dff3997 100644
--- a/src/tools/clippy/clippy_lints/src/unused_self.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_self.rs
@@ -1,12 +1,10 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::macros::root_macro_call_first_node;
-use clippy_utils::sym;
+use clippy_utils::usage::is_todo_unimplemented_stub;
use clippy_utils::visitors::is_local_used;
-use rustc_hir::{Body, Impl, ImplItem, ImplItemKind, ItemKind};
+use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
-use std::ops::ControlFlow;
declare_clippy_lint! {
/// ### What it does
@@ -60,18 +58,6 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &ImplItem<'_>)
let parent = cx.tcx.hir_get_parent_item(impl_item.hir_id()).def_id;
let parent_item = cx.tcx.hir_expect_item(parent);
let assoc_item = cx.tcx.associated_item(impl_item.owner_id);
- let contains_todo = |cx, body: &'_ Body<'_>| -> bool {
- clippy_utils::visitors::for_each_expr_without_closures(body.value, |e| {
- if let Some(macro_call) = root_macro_call_first_node(cx, e)
- && cx.tcx.is_diagnostic_item(sym::todo_macro, macro_call.def_id)
- {
- ControlFlow::Break(())
- } else {
- ControlFlow::Continue(())
- }
- })
- .is_some()
- };
if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind
&& assoc_item.is_method()
&& let ImplItemKind::Fn(.., body_id) = &impl_item.kind
@@ -79,7 +65,7 @@ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &ImplItem<'_>)
&& let body = cx.tcx.hir_body(*body_id)
&& let [self_param, ..] = body.params
&& !is_local_used(cx, body, self_param.pat.hir_id)
- && !contains_todo(cx, body)
+ && !is_todo_unimplemented_stub(cx, body.value)
{
span_lint_and_help(
cx,
diff --git a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
index b7a1d5b..12f2804 100644
--- a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
@@ -6,7 +6,7 @@
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Item, ItemKind, UseKind};
-use rustc_lint::{LateContext, LateLintPass, LintContext as _};
+use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::Visibility;
use rustc_session::impl_lint_pass;
use rustc_span::symbol::kw;
@@ -59,7 +59,7 @@ pub fn new(conf: &'static Conf) -> Self {
impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
- if !item.span.in_external_macro(cx.sess().source_map())
+ if !item.span.from_expansion()
&& let ItemKind::Use(path, UseKind::Single(ident)) = item.kind
// Ignore imports that already use Underscore
&& ident.name != kw::Underscore
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 380ddea..e5b20c0 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -176,6 +176,33 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
}
},
+ ExprKind::MethodCall(path, recv, [arg], _) => {
+ if matches!(
+ path.ident.name,
+ sym::map | sym::map_err | sym::map_break | sym::map_continue
+ ) && has_eligible_receiver(cx, recv, e)
+ && (is_trait_item(cx, arg, sym::Into) || is_trait_item(cx, arg, sym::From))
+ && let ty::FnDef(_, args) = cx.typeck_results().expr_ty(arg).kind()
+ && let &[from_ty, to_ty] = args.into_type_list(cx.tcx).as_slice()
+ && same_type_and_consts(from_ty, to_ty)
+ {
+ span_lint_and_then(
+ cx,
+ USELESS_CONVERSION,
+ e.span.with_lo(recv.span.hi()),
+ format!("useless conversion to the same type: `{from_ty}`"),
+ |diag| {
+ diag.suggest_remove_item(
+ cx,
+ e.span.with_lo(recv.span.hi()),
+ "consider removing",
+ Applicability::MachineApplicable,
+ );
+ },
+ );
+ }
+ },
+
ExprKind::MethodCall(name, recv, [], _) => {
if is_trait_method(cx, e, sym::Into) && name.ident.name == sym::into {
let a = cx.typeck_results().expr_ty(e);
@@ -412,32 +439,6 @@ fn check_expr_post(&mut self, _: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
}
}
-/// Check if `arg` is a `Into::into` or `From::from` applied to `receiver` to give `expr`, through a
-/// higher-order mapping function.
-pub fn check_function_application(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) {
- if has_eligible_receiver(cx, recv, expr)
- && (is_trait_item(cx, arg, sym::Into) || is_trait_item(cx, arg, sym::From))
- && let ty::FnDef(_, args) = cx.typeck_results().expr_ty(arg).kind()
- && let &[from_ty, to_ty] = args.into_type_list(cx.tcx).as_slice()
- && same_type_and_consts(from_ty, to_ty)
- {
- span_lint_and_then(
- cx,
- USELESS_CONVERSION,
- expr.span.with_lo(recv.span.hi()),
- format!("useless conversion to the same type: `{from_ty}`"),
- |diag| {
- diag.suggest_remove_item(
- cx,
- expr.span.with_lo(recv.span.hi()),
- "consider removing",
- Applicability::MachineApplicable,
- );
- },
- );
- }
-}
-
fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>) -> bool {
if is_inherent_method_call(cx, expr) {
matches!(
diff --git a/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs b/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
index 88b099c..41fafc0 100644
--- a/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
@@ -2,6 +2,7 @@
use clippy_utils::paths;
use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::{AttrStyle, DelimArgs};
+use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_hir::def::Res;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{
@@ -11,7 +12,6 @@
use rustc_lint_defs::declare_tool_lint;
use rustc_middle::ty::TyCtxt;
use rustc_session::declare_lint_pass;
-use rustc_span::sym;
declare_tool_lint! {
/// ### What it does
@@ -88,7 +88,10 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
}
// Is it derived?
- if !find_attr!(cx.tcx.get_all_attrs(item.owner_id), AttributeKind::AutomaticallyDerived(..)) {
+ if !find_attr!(
+ cx.tcx.get_all_attrs(item.owner_id),
+ AttributeKind::AutomaticallyDerived(..)
+ ) {
return;
}
diff --git a/src/tools/clippy/clippy_lints_internal/src/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints_internal/src/lint_without_lint_pass.rs
index 45a8660..fda65bc 100644
--- a/src/tools/clippy/clippy_lints_internal/src/lint_without_lint_pass.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/lint_without_lint_pass.rs
@@ -1,7 +1,7 @@
use crate::internal_paths;
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
-use clippy_utils::is_lint_allowed;
use clippy_utils::macros::root_macro_call_first_node;
+use clippy_utils::{is_lint_allowed, sym};
use rustc_ast::ast::LitKind;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_hir as hir;
@@ -12,9 +12,9 @@
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::Span;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::Symbol;
-use rustc_span::{Span, sym};
declare_tool_lint! {
/// ### What it does
@@ -160,9 +160,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
let body = cx.tcx.hir_body_owned_by(
impl_item_refs
.iter()
- .find(|iiref| iiref.ident.as_str() == "lint_vec")
+ .find(|&&iiref| cx.tcx.item_name(iiref.owner_id) == sym::lint_vec)
.expect("LintPass needs to implement lint_vec")
- .id
.owner_id
.def_id,
);
diff --git a/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs
index 70b3c03..66aeb91 100644
--- a/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/msrv_attr_impl.rs
@@ -1,6 +1,7 @@
use crate::internal_paths;
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
+use clippy_utils::sym;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -40,7 +41,9 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
.filter(|t| matches!(t.kind(), GenericArgKind::Type(_)))
.any(|t| internal_paths::MSRV_STACK.matches_ty(cx, t.expect_ty()))
})
- && !items.iter().any(|item| item.ident.name.as_str() == "check_attributes")
+ && !items
+ .iter()
+ .any(|&item| cx.tcx.item_name(item.owner_id) == sym::check_attributes)
{
let span = cx.sess().source_map().span_through_char(item.span, '{');
span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md
index 645b644..19e71f6 100644
--- a/src/tools/clippy/clippy_utils/README.md
+++ b/src/tools/clippy/clippy_utils/README.md
@@ -8,7 +8,7 @@
<!-- begin autogenerated nightly -->
```
-nightly-2025-07-10
+nightly-2025-07-25
```
<!-- end autogenerated nightly -->
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index 8453165..625e1ee 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -22,10 +22,13 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {
{
diag.help(format!(
"for further information visit https://rust-lang.github.io/rust-clippy/{}/index.html#{lint}",
- &option_env!("RUST_RELEASE_NUM").map_or("master".to_string(), |n| {
- // extract just major + minor version and ignore patch versions
- format!("rust-{}", n.rsplit_once('.').unwrap().1)
- })
+ &option_env!("RUST_RELEASE_NUM").map_or_else(
+ || "master".to_string(),
+ |n| {
+ // extract just major + minor version and ignore patch versions
+ format!("rust-{}", n.rsplit_once('.').unwrap().1)
+ }
+ )
));
}
}
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index ff1ee66..ce5af4d 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -89,8 +89,8 @@
use itertools::Itertools;
use rustc_abi::Integer;
-use rustc_ast::join_path_syms;
use rustc_ast::ast::{self, LitKind, RangeLimits};
+use rustc_ast::join_path_syms;
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::packed::Pu128;
@@ -114,7 +114,7 @@
use rustc_middle::hir::place::PlaceBase;
use rustc_middle::lint::LevelAndSource;
use rustc_middle::mir::{AggregateKind, Operand, RETURN_PLACE, Rvalue, StatementKind, TerminatorKind};
-use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, PointerCoercion};
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{
self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, GenericArgKind, GenericArgsRef, IntTy, Ty, TyCtxt,
@@ -1897,6 +1897,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
/// * `|x| { return x }`
/// * `|x| { return x; }`
/// * `|(x, y)| (x, y)`
+/// * `|[x, y]| [x, y]`
///
/// Consider calling [`is_expr_untyped_identity_function`] or [`is_expr_identity_function`] instead.
fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
@@ -1907,9 +1908,9 @@ fn check_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
.get(pat.hir_id)
.is_some_and(|mode| matches!(mode.0, ByRef::Yes(_)))
{
- // If a tuple `(x, y)` is of type `&(i32, i32)`, then due to match ergonomics,
- // the inner patterns become references. Don't consider this the identity function
- // as that changes types.
+ // If the parameter is `(x, y)` of type `&(T, T)`, or `[x, y]` of type `&[T; 2]`, then
+ // due to match ergonomics, the inner patterns become references. Don't consider this
+ // the identity function as that changes types.
return false;
}
@@ -1922,6 +1923,13 @@ fn check_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
{
pats.iter().zip(tup).all(|(pat, expr)| check_pat(cx, pat, expr))
},
+ (PatKind::Slice(before, slice, after), ExprKind::Array(arr))
+ if slice.is_none() && before.len() + after.len() == arr.len() =>
+ {
+ (before.iter().chain(after))
+ .zip(arr)
+ .all(|(pat, expr)| check_pat(cx, pat, expr))
+ },
_ => false,
}
}
@@ -3269,15 +3277,13 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
if go_up_by > max_super {
// `super` chain would be too long, just use the absolute path instead
- join_path_syms(
- once(kw::Crate).chain(to.data.iter().filter_map(|el| {
- if let DefPathData::TypeNs(sym) = el.data {
- Some(sym)
- } else {
- None
- }
- }))
- )
+ join_path_syms(once(kw::Crate).chain(to.data.iter().filter_map(|el| {
+ if let DefPathData::TypeNs(sym) = el.data {
+ Some(sym)
+ } else {
+ None
+ }
+ })))
} else {
join_path_syms(repeat_n(kw::Super, go_up_by).chain(path))
}
@@ -3560,3 +3566,14 @@ pub fn potential_return_of_enclosing_body(cx: &LateContext<'_>, expr: &Expr<'_>)
// enclosing body.
false
}
+
+/// Checks if the expression has adjustments that require coercion, for example: dereferencing with
+/// overloaded deref, coercing pointers and `dyn` objects.
+pub fn expr_adjustment_requires_coercion(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+ cx.typeck_results().expr_adjustments(expr).iter().any(|adj| {
+ matches!(
+ adj.kind,
+ Adjust::Deref(Some(_)) | Adjust::Pointer(PointerCoercion::Unsize) | Adjust::NeverToAny
+ )
+ })
+}
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index c681806..ea8cfc5 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -308,10 +308,11 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n
None
}
}),
- ItemKind::Impl(..) | ItemKind::Trait(..)
- => tcx.associated_items(local_id).filter_by_name_unhygienic(name)
- .find(|assoc_item| ns.matches(Some(assoc_item.namespace())))
- .map(|assoc_item| assoc_item.def_id),
+ ItemKind::Impl(..) | ItemKind::Trait(..) => tcx
+ .associated_items(local_id)
+ .filter_by_name_unhygienic(name)
+ .find(|assoc_item| ns.matches(Some(assoc_item.namespace())))
+ .map(|assoc_item| assoc_item.def_id),
_ => None,
}
}
diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs
index 8a8218c..934be97 100644
--- a/src/tools/clippy/clippy_utils/src/sym.rs
+++ b/src/tools/clippy/clippy_utils/src/sym.rs
@@ -98,6 +98,7 @@ macro_rules! generate {
ceil_char_boundary,
chain,
chars,
+ check_attributes,
checked_abs,
checked_add,
checked_isqrt,
@@ -196,6 +197,7 @@ macro_rules! generate {
kw,
last,
lazy_static,
+ lint_vec,
ln,
lock,
lock_api,
@@ -261,6 +263,7 @@ macro_rules! generate {
read_to_end,
read_to_string,
read_unaligned,
+ redundant_imports,
redundant_pub_crate,
regex,
rem_euclid,
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index fe208c0..d70232e 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -492,10 +492,7 @@ fn f(ty: Ty<'_>, count: usize, mutability: Mutability) -> (Ty<'_>, usize, Mutabi
/// Returns `true` if the given type is an `unsafe` function.
pub fn type_is_unsafe_function<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
- match ty.kind() {
- ty::FnDef(..) | ty::FnPtr(..) => ty.fn_sig(cx.tcx).safety().is_unsafe(),
- _ => false,
- }
+ ty.is_fn() && ty.fn_sig(cx.tcx).safety().is_unsafe()
}
/// Returns the base type for HIR references and pointers.
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index 84df36c..d9c7e6e 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -12,10 +12,11 @@
//! be considered a bug.
use crate::paths::{PathNS, lookup_path};
+use rustc_ast::{LitFloatType, LitIntType, LitKind};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_qpath, walk_ty};
-use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, GenericArgs, HirId, Node, PathSegment, QPath, TyKind};
+use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, GenericArgs, HirId, Node, Param, PathSegment, QPath, TyKind};
use rustc_lint::LateContext;
use rustc_middle::ty::{self, AdtDef, GenericArgKind, Ty};
use rustc_span::Span;
@@ -24,22 +25,24 @@
use certainty::{Certainty, Meet, join, meet};
pub fn expr_type_is_certain(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
- expr_type_certainty(cx, expr).is_certain()
+ expr_type_certainty(cx, expr, false).is_certain()
}
-fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
+/// Determine the type certainty of `expr`. `in_arg` indicates that the expression happens within
+/// the evaluation of a function or method call argument.
+fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>, in_arg: bool) -> Certainty {
let certainty = match &expr.kind {
ExprKind::Unary(_, expr)
| ExprKind::Field(expr, _)
| ExprKind::Index(expr, _, _)
- | ExprKind::AddrOf(_, _, expr) => expr_type_certainty(cx, expr),
+ | ExprKind::AddrOf(_, _, expr) => expr_type_certainty(cx, expr, in_arg),
- ExprKind::Array(exprs) => join(exprs.iter().map(|expr| expr_type_certainty(cx, expr))),
+ ExprKind::Array(exprs) => join(exprs.iter().map(|expr| expr_type_certainty(cx, expr, in_arg))),
ExprKind::Call(callee, args) => {
- let lhs = expr_type_certainty(cx, callee);
+ let lhs = expr_type_certainty(cx, callee, false);
let rhs = if type_is_inferable_from_arguments(cx, expr) {
- meet(args.iter().map(|arg| expr_type_certainty(cx, arg)))
+ meet(args.iter().map(|arg| expr_type_certainty(cx, arg, true)))
} else {
Certainty::Uncertain
};
@@ -47,7 +50,7 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
},
ExprKind::MethodCall(method, receiver, args, _) => {
- let mut receiver_type_certainty = expr_type_certainty(cx, receiver);
+ let mut receiver_type_certainty = expr_type_certainty(cx, receiver, false);
// Even if `receiver_type_certainty` is `Certain(Some(..))`, the `Self` type in the method
// identified by `type_dependent_def_id(..)` can differ. This can happen as a result of a `deref`,
// for example. So update the `DefId` in `receiver_type_certainty` (if any).
@@ -59,7 +62,8 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
let lhs = path_segment_certainty(cx, receiver_type_certainty, method, false);
let rhs = if type_is_inferable_from_arguments(cx, expr) {
meet(
- std::iter::once(receiver_type_certainty).chain(args.iter().map(|arg| expr_type_certainty(cx, arg))),
+ std::iter::once(receiver_type_certainty)
+ .chain(args.iter().map(|arg| expr_type_certainty(cx, arg, true))),
)
} else {
Certainty::Uncertain
@@ -67,16 +71,39 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
lhs.join(rhs)
},
- ExprKind::Tup(exprs) => meet(exprs.iter().map(|expr| expr_type_certainty(cx, expr))),
+ ExprKind::Tup(exprs) => meet(exprs.iter().map(|expr| expr_type_certainty(cx, expr, in_arg))),
- ExprKind::Binary(_, lhs, rhs) => expr_type_certainty(cx, lhs).meet(expr_type_certainty(cx, rhs)),
+ ExprKind::Binary(_, lhs, rhs) => {
+ // If one of the side of the expression is uncertain, the certainty will come from the other side,
+ // with no information on the type.
+ match (
+ expr_type_certainty(cx, lhs, in_arg),
+ expr_type_certainty(cx, rhs, in_arg),
+ ) {
+ (Certainty::Uncertain, Certainty::Certain(_)) | (Certainty::Certain(_), Certainty::Uncertain) => {
+ Certainty::Certain(None)
+ },
+ (l, r) => l.meet(r),
+ }
+ },
- ExprKind::Lit(_) => Certainty::Certain(None),
+ ExprKind::Lit(lit) => {
+ if !in_arg
+ && matches!(
+ lit.node,
+ LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed)
+ )
+ {
+ Certainty::Uncertain
+ } else {
+ Certainty::Certain(None)
+ }
+ },
ExprKind::Cast(_, ty) => type_certainty(cx, ty),
ExprKind::If(_, if_expr, Some(else_expr)) => {
- expr_type_certainty(cx, if_expr).join(expr_type_certainty(cx, else_expr))
+ expr_type_certainty(cx, if_expr, in_arg).join(expr_type_certainty(cx, else_expr, in_arg))
},
ExprKind::Path(qpath) => qpath_certainty(cx, qpath, false),
@@ -188,6 +215,20 @@ fn qpath_certainty(cx: &LateContext<'_>, qpath: &QPath<'_>, resolves_to_type: bo
certainty
}
+/// Tries to tell whether `param` resolves to something certain, e.g., a non-wildcard type if
+/// present. The certainty `DefId` is cleared before returning.
+fn param_certainty(cx: &LateContext<'_>, param: &Param<'_>) -> Certainty {
+ let owner_did = cx.tcx.hir_enclosing_body_owner(param.hir_id);
+ let Some(fn_decl) = cx.tcx.hir_fn_decl_by_hir_id(cx.tcx.local_def_id_to_hir_id(owner_did)) else {
+ return Certainty::Uncertain;
+ };
+ let inputs = fn_decl.inputs;
+ let body_params = cx.tcx.hir_body_owned_by(owner_did).params;
+ std::iter::zip(body_params, inputs)
+ .find(|(p, _)| p.hir_id == param.hir_id)
+ .map_or(Certainty::Uncertain, |(_, ty)| type_certainty(cx, ty).clear_def_id())
+}
+
fn path_segment_certainty(
cx: &LateContext<'_>,
parent_certainty: Certainty,
@@ -240,15 +281,16 @@ fn path_segment_certainty(
// `get_parent` because `hir_id` refers to a `Pat`, and we're interested in the node containing the `Pat`.
Res::Local(hir_id) => match cx.tcx.parent_hir_node(hir_id) {
- // An argument's type is always certain.
- Node::Param(..) => Certainty::Certain(None),
+ // A parameter's type is not always certain, as it may come from an untyped closure definition,
+ // or from a wildcard in a typed closure definition.
+ Node::Param(param) => param_certainty(cx, param),
// A local's type is certain if its type annotation is certain or it has an initializer whose
// type is certain.
Node::LetStmt(local) => {
let lhs = local.ty.map_or(Certainty::Uncertain, |ty| type_certainty(cx, ty));
let rhs = local
.init
- .map_or(Certainty::Uncertain, |init| expr_type_certainty(cx, init));
+ .map_or(Certainty::Uncertain, |init| expr_type_certainty(cx, init, false));
let certainty = lhs.join(rhs);
if resolves_to_type {
certainty
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index 1b049b6..76d43fe 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -1,3 +1,4 @@
+use crate::macros::root_macro_call_first_node;
use crate::visitors::{Descend, Visitable, for_each_expr, for_each_expr_without_closures};
use crate::{self as utils, get_enclosing_loop_or_multi_call_closure};
use core::ops::ControlFlow;
@@ -9,6 +10,7 @@
use rustc_middle::hir::nested_filter;
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty;
+use rustc_span::sym;
/// Returns a set of mutated local variable IDs, or `None` if mutations could not be determined.
pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> Option<HirIdSet> {
@@ -140,6 +142,46 @@ fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
}
}
+/// Checks if the given expression is a macro call to `todo!()` or `unimplemented!()`.
+pub fn is_todo_unimplemented_macro(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+ root_macro_call_first_node(cx, expr).is_some_and(|macro_call| {
+ [sym::todo_macro, sym::unimplemented_macro]
+ .iter()
+ .any(|&sym| cx.tcx.is_diagnostic_item(sym, macro_call.def_id))
+ })
+}
+
+/// Checks if the given expression is a stub, i.e., a `todo!()` or `unimplemented!()` expression,
+/// or a block whose last expression is a `todo!()` or `unimplemented!()`.
+pub fn is_todo_unimplemented_stub(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+ if let ExprKind::Block(block, _) = expr.kind {
+ if let Some(last_expr) = block.expr {
+ return is_todo_unimplemented_macro(cx, last_expr);
+ }
+
+ return block.stmts.last().is_some_and(|stmt| {
+ if let hir::StmtKind::Expr(expr) | hir::StmtKind::Semi(expr) = stmt.kind {
+ return is_todo_unimplemented_macro(cx, expr);
+ }
+ false
+ });
+ }
+
+ is_todo_unimplemented_macro(cx, expr)
+}
+
+/// Checks if the given expression contains macro call to `todo!()` or `unimplemented!()`.
+pub fn contains_todo_unimplement_macro(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {
+ for_each_expr_without_closures(expr, |e| {
+ if is_todo_unimplemented_macro(cx, e) {
+ ControlFlow::Break(())
+ } else {
+ ControlFlow::Continue(())
+ }
+ })
+ .is_some()
+}
+
pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool {
for_each_expr_without_closures(expression, |e| {
match e.kind {
diff --git a/src/tools/clippy/rust-toolchain.toml b/src/tools/clippy/rust-toolchain.toml
index f46e079..0edb80e 100644
--- a/src/tools/clippy/rust-toolchain.toml
+++ b/src/tools/clippy/rust-toolchain.toml
@@ -1,6 +1,6 @@
[toolchain]
# begin autogenerated nightly
-channel = "nightly-2025-07-10"
+channel = "nightly-2025-07-25"
# end autogenerated nightly
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
profile = "minimal"
diff --git a/src/tools/clippy/rustc_tools_util/src/lib.rs b/src/tools/clippy/rustc_tools_util/src/lib.rs
index b45edf2..194ed84 100644
--- a/src/tools/clippy/rustc_tools_util/src/lib.rs
+++ b/src/tools/clippy/rustc_tools_util/src/lib.rs
@@ -157,7 +157,8 @@ pub fn get_commit_date() -> Option<String> {
#[must_use]
pub fn get_compiler_version() -> Option<String> {
- get_output("rustc", &["-V"])
+ let compiler = std::option_env!("RUSTC").unwrap_or("rustc");
+ get_output(compiler, &["-V"])
}
#[must_use]
@@ -172,6 +173,8 @@ pub fn get_channel(compiler_version: Option<String>) -> String {
return String::from("beta");
} else if rustc_output.contains("nightly") {
return String::from("nightly");
+ } else if rustc_output.contains("dev") {
+ return String::from("dev");
}
}
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 83f91cc..464efc4 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -162,6 +162,10 @@ fn base_config(&self, test_dir: &str, mandatory_annotations: bool) -> Config {
// however has some staging logic that is hurting us here, so to work around
// that we set both the "real" and "staging" rustc to TEST_RUSTC, including the
// associated library paths.
+ #[expect(
+ clippy::option_env_unwrap,
+ reason = "TEST_RUSTC will ensure that the requested env vars are set during compile time"
+ )]
if let Some(rustc) = option_env!("TEST_RUSTC") {
let libdir = option_env!("TEST_RUSTC_LIB").unwrap();
let sysroot = option_env!("TEST_SYSROOT").unwrap();
@@ -169,10 +173,7 @@ fn base_config(&self, test_dir: &str, mandatory_annotations: bool) -> Config {
p.envs.push(("RUSTC_REAL_LIBDIR".into(), Some(libdir.into())));
p.envs.push(("RUSTC_SNAPSHOT".into(), Some(rustc.into())));
p.envs.push(("RUSTC_SNAPSHOT_LIBDIR".into(), Some(libdir.into())));
- p.envs.push((
- "RUSTC_SYSROOT".into(),
- Some(sysroot.into()),
- ));
+ p.envs.push(("RUSTC_SYSROOT".into(), Some(sysroot.into())));
}
p
},
diff --git a/src/tools/clippy/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr b/src/tools/clippy/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr
index 8a85d38..608264b 100644
--- a/src/tools/clippy/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr
+++ b/src/tools/clippy/tests/ui-toml/check_incompatible_msrv_in_tests/check_incompatible_msrv_in_tests.enabled.stderr
@@ -18,6 +18,8 @@
|
LL | sleep(Duration::new(1, 0));
| ^^^^^
+ |
+ = note: you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
index 020b3cc..a5dfd70 100644
--- a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
@@ -12,7 +12,7 @@
|
= note: `-D clippy::large-enum-variant` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B([u8; 501]),
LL + B(Box<[u8; 501]>),
diff --git a/src/tools/clippy/tests/ui/approx_const.rs b/src/tools/clippy/tests/ui/approx_const.rs
index 6461666..fc49342 100644
--- a/src/tools/clippy/tests/ui/approx_const.rs
+++ b/src/tools/clippy/tests/ui/approx_const.rs
@@ -106,4 +106,19 @@ fn main() {
//~^ approx_constant
let no_tau = 6.3;
+
+ // issue #15194
+ #[allow(clippy::excessive_precision)]
+ let x: f64 = 3.1415926535897932384626433832;
+ //~^ approx_constant
+
+ #[allow(clippy::excessive_precision)]
+ let _: f64 = 003.14159265358979311599796346854418516159057617187500;
+ //~^ approx_constant
+
+ let almost_frac_1_sqrt_2 = 00.70711;
+ //~^ approx_constant
+
+ let almost_frac_1_sqrt_2 = 00.707_11;
+ //~^ approx_constant
}
diff --git a/src/tools/clippy/tests/ui/approx_const.stderr b/src/tools/clippy/tests/ui/approx_const.stderr
index f7bda04..32a3517 100644
--- a/src/tools/clippy/tests/ui/approx_const.stderr
+++ b/src/tools/clippy/tests/ui/approx_const.stderr
@@ -184,5 +184,37 @@
|
= help: consider using the constant directly
-error: aborting due to 23 previous errors
+error: approximate value of `f{32, 64}::consts::PI` found
+ --> tests/ui/approx_const.rs:112:18
+ |
+LL | let x: f64 = 3.1415926535897932384626433832;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using the constant directly
+
+error: approximate value of `f{32, 64}::consts::PI` found
+ --> tests/ui/approx_const.rs:116:18
+ |
+LL | let _: f64 = 003.14159265358979311599796346854418516159057617187500;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider using the constant directly
+
+error: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found
+ --> tests/ui/approx_const.rs:119:32
+ |
+LL | let almost_frac_1_sqrt_2 = 00.70711;
+ | ^^^^^^^^
+ |
+ = help: consider using the constant directly
+
+error: approximate value of `f{32, 64}::consts::FRAC_1_SQRT_2` found
+ --> tests/ui/approx_const.rs:122:32
+ |
+LL | let almost_frac_1_sqrt_2 = 00.707_11;
+ | ^^^^^^^^^
+ |
+ = help: consider using the constant directly
+
+error: aborting due to 27 previous errors
diff --git a/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr b/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr
index 5556b0d..ce72620 100644
--- a/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr
+++ b/src/tools/clippy/tests/ui/arc_with_non_send_sync.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Arc<RefCell<i32>>` is not `Send` and `Sync` as `RefCell<i32>` is not `Sync`
- = help: if the `Arc` will not used be across threads replace it with an `Rc`
+ = help: if the `Arc` will not be used across threads replace it with an `Rc`
= help: otherwise make `RefCell<i32>` `Send` and `Sync` or consider a wrapper type such as `Mutex`
= note: `-D clippy::arc-with-non-send-sync` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::arc_with_non_send_sync)]`
@@ -17,7 +17,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Arc<MutexGuard<'_, i32>>` is not `Send` and `Sync` as `MutexGuard<'_, i32>` is not `Send`
- = help: if the `Arc` will not used be across threads replace it with an `Rc`
+ = help: if the `Arc` will not be used across threads replace it with an `Rc`
= help: otherwise make `MutexGuard<'_, i32>` `Send` and `Sync` or consider a wrapper type such as `Mutex`
error: usage of an `Arc` that is not `Send` and `Sync`
@@ -27,7 +27,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Arc<*const i32>` is not `Send` and `Sync` as `*const i32` is neither `Send` nor `Sync`
- = help: if the `Arc` will not used be across threads replace it with an `Rc`
+ = help: if the `Arc` will not be used across threads replace it with an `Rc`
= help: otherwise make `*const i32` `Send` and `Sync` or consider a wrapper type such as `Mutex`
error: aborting due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
index 21be2af..3245b2c 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
@@ -664,6 +664,20 @@ pub fn issue_12318() {
//~^ arithmetic_side_effects
}
+pub fn issue_15225() {
+ use core::num::{NonZero, NonZeroU8};
+
+ let one = const { NonZeroU8::new(1).unwrap() };
+ let _ = one.get() - 1;
+
+ let one: NonZero<u8> = const { NonZero::new(1).unwrap() };
+ let _ = one.get() - 1;
+
+ type AliasedType = u8;
+ let one: NonZero<AliasedType> = const { NonZero::new(1).unwrap() };
+ let _ = one.get() - 1;
+}
+
pub fn explicit_methods() {
use core::ops::Add;
let one: i32 = 1;
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
index e15fb61..4150493 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -758,13 +758,13 @@
| ^^^^^^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> tests/ui/arithmetic_side_effects.rs:670:5
+ --> tests/ui/arithmetic_side_effects.rs:684:5
|
LL | one.add(&one);
| ^^^^^^^^^^^^^
error: arithmetic operation that can potentially result in unexpected side-effects
- --> tests/ui/arithmetic_side_effects.rs:672:5
+ --> tests/ui/arithmetic_side_effects.rs:686:5
|
LL | Box::new(one).add(one);
| ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/assign_ops.fixed b/src/tools/clippy/tests/ui/assign_ops.fixed
index eee61f9..3754b9d 100644
--- a/src/tools/clippy/tests/ui/assign_ops.fixed
+++ b/src/tools/clippy/tests/ui/assign_ops.fixed
@@ -84,6 +84,7 @@
const ONE: Self;
}
+ #[rustfmt::skip] // rustfmt doesn't understand the order of pub const on traits (yet)
pub const trait NumberConstants {
fn constant(value: usize) -> Self;
}
diff --git a/src/tools/clippy/tests/ui/assign_ops.rs b/src/tools/clippy/tests/ui/assign_ops.rs
index 13ffcee..0b878d4 100644
--- a/src/tools/clippy/tests/ui/assign_ops.rs
+++ b/src/tools/clippy/tests/ui/assign_ops.rs
@@ -84,6 +84,7 @@ pub trait Number: Copy + Add<Self, Output = Self> + AddAssign {
const ONE: Self;
}
+ #[rustfmt::skip] // rustfmt doesn't understand the order of pub const on traits (yet)
pub const trait NumberConstants {
fn constant(value: usize) -> Self;
}
diff --git a/src/tools/clippy/tests/ui/auxiliary/external_item.rs b/src/tools/clippy/tests/ui/auxiliary/external_item.rs
index ca4bc36..621e18f 100644
--- a/src/tools/clippy/tests/ui/auxiliary/external_item.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/external_item.rs
@@ -4,4 +4,4 @@ impl _ExternalStruct {
pub fn _foo(self) {}
}
-pub fn _exernal_foo() {}
+pub fn _external_foo() {}
diff --git a/src/tools/clippy/tests/ui/checked_conversions.fixed b/src/tools/clippy/tests/ui/checked_conversions.fixed
index 279a5b6..6175275 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.fixed
+++ b/src/tools/clippy/tests/ui/checked_conversions.fixed
@@ -95,7 +95,7 @@
#[clippy::msrv = "1.33"]
fn msrv_1_33() {
let value: i64 = 33;
- let _ = value <= (u32::MAX as i64) && value >= 0;
+ let _ = value <= (u32::max_value() as i64) && value >= 0;
}
#[clippy::msrv = "1.34"]
diff --git a/src/tools/clippy/tests/ui/checked_conversions.rs b/src/tools/clippy/tests/ui/checked_conversions.rs
index c339bc6..9ed0e8f 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.rs
+++ b/src/tools/clippy/tests/ui/checked_conversions.rs
@@ -95,13 +95,13 @@ pub const fn issue_8898(i: u32) -> bool {
#[clippy::msrv = "1.33"]
fn msrv_1_33() {
let value: i64 = 33;
- let _ = value <= (u32::MAX as i64) && value >= 0;
+ let _ = value <= (u32::max_value() as i64) && value >= 0;
}
#[clippy::msrv = "1.34"]
fn msrv_1_34() {
let value: i64 = 34;
- let _ = value <= (u32::MAX as i64) && value >= 0;
+ let _ = value <= (u32::max_value() as i64) && value >= 0;
//~^ checked_conversions
}
diff --git a/src/tools/clippy/tests/ui/checked_conversions.stderr b/src/tools/clippy/tests/ui/checked_conversions.stderr
index 3841b9d..624876d 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.stderr
+++ b/src/tools/clippy/tests/ui/checked_conversions.stderr
@@ -100,8 +100,8 @@
error: checked cast can be simplified
--> tests/ui/checked_conversions.rs:104:13
|
-LL | let _ = value <= (u32::MAX as i64) && value >= 0;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
+LL | let _ = value <= (u32::max_value() as i64) && value >= 0;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
error: aborting due to 17 previous errors
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
index a4bf009..26e3601 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
@@ -328,7 +328,7 @@
LL | if X.is_some() {
| ^^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[deny(static_mut_refs)]` on by default
diff --git a/src/tools/clippy/tests/ui/expect.rs b/src/tools/clippy/tests/ui/expect.rs
index 8f7379f..1ab01ec 100644
--- a/src/tools/clippy/tests/ui/expect.rs
+++ b/src/tools/clippy/tests/ui/expect.rs
@@ -16,7 +16,26 @@ fn expect_result() {
//~^ expect_used
}
+#[allow(clippy::ok_expect)]
+#[allow(clippy::err_expect)]
+fn issue_15247() {
+ let x: Result<u8, u8> = Err(0);
+ x.ok().expect("Huh");
+ //~^ expect_used
+
+ { x.ok() }.expect("...");
+ //~^ expect_used
+
+ let y: Result<u8, u8> = Ok(0);
+ y.err().expect("Huh");
+ //~^ expect_used
+
+ { y.err() }.expect("...");
+ //~^ expect_used
+}
+
fn main() {
expect_option();
expect_result();
+ issue_15247();
}
diff --git a/src/tools/clippy/tests/ui/expect.stderr b/src/tools/clippy/tests/ui/expect.stderr
index 70cf307..353fb77 100644
--- a/src/tools/clippy/tests/ui/expect.stderr
+++ b/src/tools/clippy/tests/ui/expect.stderr
@@ -24,5 +24,37 @@
|
= note: if this value is an `Ok`, it will panic
-error: aborting due to 3 previous errors
+error: used `expect()` on an `Option` value
+ --> tests/ui/expect.rs:23:5
+ |
+LL | x.ok().expect("Huh");
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: if this value is `None`, it will panic
+
+error: used `expect()` on an `Option` value
+ --> tests/ui/expect.rs:26:5
+ |
+LL | { x.ok() }.expect("...");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: if this value is `None`, it will panic
+
+error: used `expect()` on an `Option` value
+ --> tests/ui/expect.rs:30:5
+ |
+LL | y.err().expect("Huh");
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: if this value is `None`, it will panic
+
+error: used `expect()` on an `Option` value
+ --> tests/ui/expect.rs:33:5
+ |
+LL | { y.err() }.expect("...");
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: if this value is `None`, it will panic
+
+error: aborting due to 7 previous errors
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.fixed b/src/tools/clippy/tests/ui/expect_fun_call.fixed
index 73eaebf..b923521 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/expect_fun_call.fixed
@@ -90,17 +90,30 @@
"foo"
}
- Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) });
+ const fn const_evaluable() -> &'static str {
+ "foo"
+ }
+
+ Some("foo").unwrap_or_else(|| panic!("{}", get_string()));
//~^ expect_fun_call
- Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) });
+ Some("foo").unwrap_or_else(|| panic!("{}", get_string()));
//~^ expect_fun_call
- Some("foo").unwrap_or_else(|| { panic!("{}", get_string()) });
+ Some("foo").unwrap_or_else(|| panic!("{}", get_string()));
//~^ expect_fun_call
- Some("foo").unwrap_or_else(|| { panic!("{}", get_static_str()) });
+ Some("foo").unwrap_or_else(|| panic!("{}", get_static_str()));
//~^ expect_fun_call
- Some("foo").unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) });
+ Some("foo").unwrap_or_else(|| panic!("{}", get_non_static_str(&0)));
//~^ expect_fun_call
+
+ Some("foo").unwrap_or_else(|| panic!("{}", const_evaluable()));
+ //~^ expect_fun_call
+
+ const {
+ Some("foo").expect(const_evaluable());
+ }
+
+ Some("foo").expect(const { const_evaluable() });
}
//Issue #3839
@@ -122,4 +135,15 @@
let format_capture_and_value: Option<i32> = None;
format_capture_and_value.unwrap_or_else(|| panic!("{error_code}, {}", 1));
//~^ expect_fun_call
+
+ // Issue #15056
+ let a = false;
+ Some(5).expect(if a { "a" } else { "b" });
+
+ let return_in_expect: Option<i32> = None;
+ return_in_expect.expect(if true {
+ "Error"
+ } else {
+ return;
+ });
}
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.rs b/src/tools/clippy/tests/ui/expect_fun_call.rs
index ecebc9e..bc58d24 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.rs
+++ b/src/tools/clippy/tests/ui/expect_fun_call.rs
@@ -90,6 +90,10 @@ fn get_non_static_str(_: &u32) -> &str {
"foo"
}
+ const fn const_evaluable() -> &'static str {
+ "foo"
+ }
+
Some("foo").expect(&get_string());
//~^ expect_fun_call
Some("foo").expect(get_string().as_ref());
@@ -101,6 +105,15 @@ fn get_non_static_str(_: &u32) -> &str {
//~^ expect_fun_call
Some("foo").expect(get_non_static_str(&0));
//~^ expect_fun_call
+
+ Some("foo").expect(const_evaluable());
+ //~^ expect_fun_call
+
+ const {
+ Some("foo").expect(const_evaluable());
+ }
+
+ Some("foo").expect(const { const_evaluable() });
}
//Issue #3839
@@ -122,4 +135,15 @@ fn get_non_static_str(_: &u32) -> &str {
let format_capture_and_value: Option<i32> = None;
format_capture_and_value.expect(&format!("{error_code}, {}", 1));
//~^ expect_fun_call
+
+ // Issue #15056
+ let a = false;
+ Some(5).expect(if a { "a" } else { "b" });
+
+ let return_in_expect: Option<i32> = None;
+ return_in_expect.expect(if true {
+ "Error"
+ } else {
+ return;
+ });
}
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.stderr b/src/tools/clippy/tests/ui/expect_fun_call.stderr
index 3671319..0692ecb 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/expect_fun_call.stderr
@@ -38,58 +38,64 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{} {}", 1, 2))`
error: function call inside of `expect`
- --> tests/ui/expect_fun_call.rs:93:21
- |
-LL | Some("foo").expect(&get_string());
- | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
-
-error: function call inside of `expect`
- --> tests/ui/expect_fun_call.rs:95:21
- |
-LL | Some("foo").expect(get_string().as_ref());
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
-
-error: function call inside of `expect`
--> tests/ui/expect_fun_call.rs:97:21
|
-LL | Some("foo").expect(get_string().as_str());
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
+LL | Some("foo").expect(&get_string());
+ | ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", get_string()))`
error: function call inside of `expect`
- --> tests/ui/expect_fun_call.rs:100:21
+ --> tests/ui/expect_fun_call.rs:99:21
+ |
+LL | Some("foo").expect(get_string().as_ref());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", get_string()))`
+
+error: function call inside of `expect`
+ --> tests/ui/expect_fun_call.rs:101:21
+ |
+LL | Some("foo").expect(get_string().as_str());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", get_string()))`
+
+error: function call inside of `expect`
+ --> tests/ui/expect_fun_call.rs:104:21
|
LL | Some("foo").expect(get_static_str());
- | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_static_str()) })`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", get_static_str()))`
error: function call inside of `expect`
- --> tests/ui/expect_fun_call.rs:102:21
+ --> tests/ui/expect_fun_call.rs:106:21
|
LL | Some("foo").expect(get_non_static_str(&0));
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", get_non_static_str(&0)))`
error: function call inside of `expect`
- --> tests/ui/expect_fun_call.rs:107:16
+ --> tests/ui/expect_fun_call.rs:109:21
+ |
+LL | Some("foo").expect(const_evaluable());
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{}", const_evaluable()))`
+
+error: function call inside of `expect`
+ --> tests/ui/expect_fun_call.rs:120:16
|
LL | Some(true).expect(&format!("key {}, {}", 1, 2));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))`
error: function call inside of `expect`
- --> tests/ui/expect_fun_call.rs:114:17
+ --> tests/ui/expect_fun_call.rs:127:17
|
LL | opt_ref.expect(&format!("{:?}", opt_ref));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{:?}", opt_ref))`
error: function call inside of `expect`
- --> tests/ui/expect_fun_call.rs:119:20
+ --> tests/ui/expect_fun_call.rs:132:20
|
LL | format_capture.expect(&format!("{error_code}"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}"))`
error: function call inside of `expect`
- --> tests/ui/expect_fun_call.rs:123:30
+ --> tests/ui/expect_fun_call.rs:136:30
|
LL | format_capture_and_value.expect(&format!("{error_code}, {}", 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))`
-error: aborting due to 15 previous errors
+error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.fixed b/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
index b3e112f..d370b85 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
@@ -89,3 +89,24 @@
let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ****b).map(|(i, b)| i).collect();
//~^ filter_map_bool_then
}
+
+fn issue15047() {
+ #[derive(Clone, Copy)]
+ enum MyEnum {
+ A,
+ B,
+ C,
+ }
+
+ macro_rules! foo {
+ ($e:expr) => {
+ $e + 1
+ };
+ }
+
+ let x = 1;
+ let _ = [(MyEnum::A, "foo", 1i32)]
+ .iter()
+ .filter(|&(t, s, i)| matches!(t, MyEnum::A if s.starts_with("bar"))).map(|(t, s, i)| foo!(x));
+ //~^ filter_map_bool_then
+}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.rs b/src/tools/clippy/tests/ui/filter_map_bool_then.rs
index d996b3c..12295cc 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.rs
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.rs
@@ -89,3 +89,24 @@ fn deref(&self) -> &Self::Target {
let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
//~^ filter_map_bool_then
}
+
+fn issue15047() {
+ #[derive(Clone, Copy)]
+ enum MyEnum {
+ A,
+ B,
+ C,
+ }
+
+ macro_rules! foo {
+ ($e:expr) => {
+ $e + 1
+ };
+ }
+
+ let x = 1;
+ let _ = [(MyEnum::A, "foo", 1i32)]
+ .iter()
+ .filter_map(|(t, s, i)| matches!(t, MyEnum::A if s.starts_with("bar")).then(|| foo!(x)));
+ //~^ filter_map_bool_then
+}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.stderr b/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
index aeb1bae..edf6c65 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
@@ -61,5 +61,11 @@
LL | let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ****b).map(|(i, b)| i)`
-error: aborting due to 10 previous errors
+error: usage of `bool::then` in `filter_map`
+ --> tests/ui/filter_map_bool_then.rs:110:10
+ |
+LL | .filter_map(|(t, s, i)| matches!(t, MyEnum::A if s.starts_with("bar")).then(|| foo!(x)));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(t, s, i)| matches!(t, MyEnum::A if s.starts_with("bar"))).map(|(t, s, i)| foo!(x))`
+
+error: aborting due to 11 previous errors
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.fixed b/src/tools/clippy/tests/ui/flat_map_identity.fixed
index f620623..06a3eee 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.fixed
+++ b/src/tools/clippy/tests/ui/flat_map_identity.fixed
@@ -16,3 +16,16 @@
let _ = iterator.flatten();
//~^ flat_map_identity
}
+
+fn issue15198() {
+ let x = [[1, 2], [3, 4]];
+ // don't lint: this is an `Iterator<Item = &[i32, i32]>`
+ // match ergonomics makes the binding patterns into references
+ // so that its type changes to `Iterator<Item = [&i32, &i32]>`
+ let _ = x.iter().flat_map(|[x, y]| [x, y]);
+ let _ = x.iter().flat_map(|x| [x[0]]);
+
+ // no match ergonomics for `[i32, i32]`
+ let _ = x.iter().copied().flatten();
+ //~^ flat_map_identity
+}
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.rs b/src/tools/clippy/tests/ui/flat_map_identity.rs
index c59e749..1cab7d5 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.rs
+++ b/src/tools/clippy/tests/ui/flat_map_identity.rs
@@ -16,3 +16,16 @@ fn main() {
let _ = iterator.flat_map(|x| return x);
//~^ flat_map_identity
}
+
+fn issue15198() {
+ let x = [[1, 2], [3, 4]];
+ // don't lint: this is an `Iterator<Item = &[i32, i32]>`
+ // match ergonomics makes the binding patterns into references
+ // so that its type changes to `Iterator<Item = [&i32, &i32]>`
+ let _ = x.iter().flat_map(|[x, y]| [x, y]);
+ let _ = x.iter().flat_map(|x| [x[0]]);
+
+ // no match ergonomics for `[i32, i32]`
+ let _ = x.iter().copied().flat_map(|[x, y]| [x, y]);
+ //~^ flat_map_identity
+}
diff --git a/src/tools/clippy/tests/ui/flat_map_identity.stderr b/src/tools/clippy/tests/ui/flat_map_identity.stderr
index 75137f5..18c863b 100644
--- a/src/tools/clippy/tests/ui/flat_map_identity.stderr
+++ b/src/tools/clippy/tests/ui/flat_map_identity.stderr
@@ -19,5 +19,11 @@
LL | let _ = iterator.flat_map(|x| return x);
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
-error: aborting due to 3 previous errors
+error: use of `flat_map` with an identity function
+ --> tests/ui/flat_map_identity.rs:29:31
+ |
+LL | let _ = x.iter().copied().flat_map(|[x, y]| [x, y]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: aborting due to 4 previous errors
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.fixed b/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
index f774608..d14a805 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
@@ -122,3 +122,46 @@
// Should not issue an error in `const` context
if x > 42 { Some(150) } else { None }
}
+
+mod issue15257 {
+ struct Range {
+ start: u8,
+ end: u8,
+ }
+
+ fn can_be_safely_rewrite(rs: &[&Range]) -> Option<Vec<u8>> {
+ (rs.len() == 1 && rs[0].start == rs[0].end).then(|| vec![rs[0].start])
+ }
+
+ fn reborrow_as_ptr(i: *mut i32) -> Option<*const i32> {
+ let modulo = unsafe { *i % 2 };
+ (modulo == 0).then_some(i)
+ }
+
+ fn reborrow_as_fn_ptr(i: i32) {
+ fn do_something(fn_: Option<fn(i32)>) {
+ todo!()
+ }
+
+ fn item_fn(i: i32) {
+ todo!()
+ }
+
+ do_something((i % 2 == 0).then_some(item_fn));
+ }
+
+ fn reborrow_as_fn_unsafe(i: i32) {
+ fn do_something(fn_: Option<unsafe fn(i32)>) {
+ todo!()
+ }
+
+ fn item_fn(i: i32) {
+ todo!()
+ }
+
+ do_something((i % 2 == 0).then_some(item_fn));
+
+ let closure_fn = |i: i32| {};
+ do_something((i % 2 == 0).then_some(closure_fn));
+ }
+}
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.rs b/src/tools/clippy/tests/ui/if_then_some_else_none.rs
index 8b8ff0a..bb0072f 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.rs
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.rs
@@ -143,3 +143,71 @@ const fn issue12103(x: u32) -> Option<u32> {
// Should not issue an error in `const` context
if x > 42 { Some(150) } else { None }
}
+
+mod issue15257 {
+ struct Range {
+ start: u8,
+ end: u8,
+ }
+
+ fn can_be_safely_rewrite(rs: &[&Range]) -> Option<Vec<u8>> {
+ if rs.len() == 1 && rs[0].start == rs[0].end {
+ //~^ if_then_some_else_none
+ Some(vec![rs[0].start])
+ } else {
+ None
+ }
+ }
+
+ fn reborrow_as_ptr(i: *mut i32) -> Option<*const i32> {
+ let modulo = unsafe { *i % 2 };
+ if modulo == 0 {
+ //~^ if_then_some_else_none
+ Some(i)
+ } else {
+ None
+ }
+ }
+
+ fn reborrow_as_fn_ptr(i: i32) {
+ fn do_something(fn_: Option<fn(i32)>) {
+ todo!()
+ }
+
+ fn item_fn(i: i32) {
+ todo!()
+ }
+
+ do_something(if i % 2 == 0 {
+ //~^ if_then_some_else_none
+ Some(item_fn)
+ } else {
+ None
+ });
+ }
+
+ fn reborrow_as_fn_unsafe(i: i32) {
+ fn do_something(fn_: Option<unsafe fn(i32)>) {
+ todo!()
+ }
+
+ fn item_fn(i: i32) {
+ todo!()
+ }
+
+ do_something(if i % 2 == 0 {
+ //~^ if_then_some_else_none
+ Some(item_fn)
+ } else {
+ None
+ });
+
+ let closure_fn = |i: i32| {};
+ do_something(if i % 2 == 0 {
+ //~^ if_then_some_else_none
+ Some(closure_fn)
+ } else {
+ None
+ });
+ }
+}
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
index 7128557..c2e624a 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
@@ -58,5 +58,63 @@
LL | if s == "1" { Some(true) } else { None }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(s == "1").then(|| true)`
-error: aborting due to 6 previous errors
+error: this could be simplified with `bool::then`
+ --> tests/ui/if_then_some_else_none.rs:154:9
+ |
+LL | / if rs.len() == 1 && rs[0].start == rs[0].end {
+LL | |
+LL | | Some(vec![rs[0].start])
+LL | | } else {
+LL | | None
+LL | | }
+ | |_________^ help: try: `(rs.len() == 1 && rs[0].start == rs[0].end).then(|| vec![rs[0].start])`
+
+error: this could be simplified with `bool::then_some`
+ --> tests/ui/if_then_some_else_none.rs:164:9
+ |
+LL | / if modulo == 0 {
+LL | |
+LL | | Some(i)
+LL | | } else {
+LL | | None
+LL | | }
+ | |_________^ help: try: `(modulo == 0).then_some(i)`
+
+error: this could be simplified with `bool::then_some`
+ --> tests/ui/if_then_some_else_none.rs:181:22
+ |
+LL | do_something(if i % 2 == 0 {
+ | ______________________^
+LL | |
+LL | | Some(item_fn)
+LL | | } else {
+LL | | None
+LL | | });
+ | |_________^ help: try: `(i % 2 == 0).then_some(item_fn)`
+
+error: this could be simplified with `bool::then_some`
+ --> tests/ui/if_then_some_else_none.rs:198:22
+ |
+LL | do_something(if i % 2 == 0 {
+ | ______________________^
+LL | |
+LL | | Some(item_fn)
+LL | | } else {
+LL | | None
+LL | | });
+ | |_________^ help: try: `(i % 2 == 0).then_some(item_fn)`
+
+error: this could be simplified with `bool::then_some`
+ --> tests/ui/if_then_some_else_none.rs:206:22
+ |
+LL | do_something(if i % 2 == 0 {
+ | ______________________^
+LL | |
+LL | | Some(closure_fn)
+LL | | } else {
+LL | | None
+LL | | });
+ | |_________^ help: try: `(i % 2 == 0).then_some(closure_fn)`
+
+error: aborting due to 11 previous errors
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none_unfixable.rs b/src/tools/clippy/tests/ui/if_then_some_else_none_unfixable.rs
new file mode 100644
index 0000000..be04299
--- /dev/null
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none_unfixable.rs
@@ -0,0 +1,35 @@
+#![warn(clippy::if_then_some_else_none)]
+#![allow(clippy::manual_is_multiple_of)]
+
+mod issue15257 {
+ use std::pin::Pin;
+
+ #[derive(Default)]
+ pub struct Foo {}
+ pub trait Bar {}
+ impl Bar for Foo {}
+
+ fn pointer_unsized_coercion(i: u32) -> Option<Box<dyn Bar>> {
+ if i % 2 == 0 {
+ //~^ if_then_some_else_none
+ Some(Box::new(Foo::default()))
+ } else {
+ None
+ }
+ }
+
+ fn reborrow_as_pin(i: Pin<&mut i32>) {
+ use std::ops::Rem;
+
+ fn do_something(i: Option<&i32>) {
+ todo!()
+ }
+
+ do_something(if i.rem(2) == 0 {
+ //~^ if_then_some_else_none
+ Some(&i)
+ } else {
+ None
+ });
+ }
+}
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none_unfixable.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none_unfixable.stderr
new file mode 100644
index 0000000..f77ce79
--- /dev/null
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none_unfixable.stderr
@@ -0,0 +1,28 @@
+error: this could be simplified with `bool::then`
+ --> tests/ui/if_then_some_else_none_unfixable.rs:13:9
+ |
+LL | / if i % 2 == 0 {
+LL | |
+LL | | Some(Box::new(Foo::default()))
+LL | | } else {
+LL | | None
+LL | | }
+ | |_________^
+ |
+ = note: `-D clippy::if-then-some-else-none` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::if_then_some_else_none)]`
+
+error: this could be simplified with `bool::then`
+ --> tests/ui/if_then_some_else_none_unfixable.rs:28:22
+ |
+LL | do_something(if i.rem(2) == 0 {
+ | ______________________^
+LL | |
+LL | | Some(&i)
+LL | | } else {
+LL | | None
+LL | | });
+ | |_________^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.rs b/src/tools/clippy/tests/ui/incompatible_msrv.rs
index 99101b2..f7f21e1 100644
--- a/src/tools/clippy/tests/ui/incompatible_msrv.rs
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.rs
@@ -1,8 +1,10 @@
#![warn(clippy::incompatible_msrv)]
#![feature(custom_inner_attributes)]
-#![feature(panic_internals)]
+#![allow(stable_features)]
+#![feature(strict_provenance)] // For use in test
#![clippy::msrv = "1.3.0"]
+use std::cell::Cell;
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::future::Future;
@@ -13,6 +15,8 @@ fn foo() {
let mut map: HashMap<&str, u32> = HashMap::new();
assert_eq!(map.entry("poneyland").key(), &"poneyland");
//~^ incompatible_msrv
+ //~| NOTE: `-D clippy::incompatible-msrv` implied by `-D warnings`
+ //~| HELP: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`
if let Entry::Vacant(v) = map.entry("poneyland") {
v.into_key();
@@ -23,6 +27,18 @@ fn foo() {
//~^ incompatible_msrv
}
+#[clippy::msrv = "1.2.0"]
+static NO_BODY_BAD_MSRV: Option<Duration> = None;
+//~^ incompatible_msrv
+
+static NO_BODY_GOOD_MSRV: Option<Duration> = None;
+
+#[clippy::msrv = "1.2.0"]
+fn bad_type_msrv() {
+ let _: Option<Duration> = None;
+ //~^ incompatible_msrv
+}
+
#[test]
fn test() {
sleep(Duration::new(1, 0));
@@ -43,21 +59,22 @@ fn core_special_treatment(p: bool) {
// But still lint code calling `core` functions directly
if p {
- core::panicking::panic("foo");
- //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+ let _ = core::iter::once_with(|| 0);
+ //~^ incompatible_msrv
}
// Lint code calling `core` from non-`core` macros
macro_rules! my_panic {
($msg:expr) => {
- core::panicking::panic($msg)
- }; //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+ let _ = core::iter::once_with(|| $msg);
+ //~^ incompatible_msrv
+ };
}
my_panic!("foo");
// Lint even when the macro comes from `core` and calls `core` functions
- assert!(core::panicking::panic("out of luck"));
- //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+ assert!(core::iter::once_with(|| 0).next().is_some());
+ //~^ incompatible_msrv
}
#[clippy::msrv = "1.26.0"]
@@ -70,7 +87,85 @@ fn lang_items() {
#[clippy::msrv = "1.80.0"]
fn issue14212() {
let _ = std::iter::repeat_n((), 5);
- //~^ ERROR: is `1.80.0` but this item is stable since `1.82.0`
+ //~^ incompatible_msrv
+}
+
+#[clippy::msrv = "1.0.0"]
+fn cstr_and_cstring_ok() {
+ let _: Option<&'static std::ffi::CStr> = None;
+ let _: Option<std::ffi::CString> = None;
+}
+
+fn local_msrv_change_suggestion() {
+ let _ = std::iter::repeat_n((), 5);
+ //~^ incompatible_msrv
+
+ #[cfg(any(test, not(test)))]
+ {
+ let _ = std::iter::repeat_n((), 5);
+ //~^ incompatible_msrv
+ //~| NOTE: you may want to conditionally increase the MSRV
+
+ // Emit the additional note only once
+ let _ = std::iter::repeat_n((), 5);
+ //~^ incompatible_msrv
+ }
+}
+
+#[clippy::msrv = "1.78.0"]
+fn feature_enable_14425(ptr: *const u8) -> usize {
+ // Do not warn, because it is enabled through a feature even though
+ // it is stabilized only since Rust 1.84.0.
+ let r = ptr.addr();
+
+ // Warn about this which has been introduced in the same Rust version
+ // but is not allowed through a feature.
+ r.isqrt()
+ //~^ incompatible_msrv
+}
+
+fn non_fn_items() {
+ let _ = std::io::ErrorKind::CrossesDevices;
+ //~^ incompatible_msrv
+}
+
+#[clippy::msrv = "1.87.0"]
+fn msrv_non_ok_in_const() {
+ {
+ let c = Cell::new(42);
+ _ = c.get();
+ }
+ const {
+ let c = Cell::new(42);
+ _ = c.get();
+ //~^ incompatible_msrv
+ }
+}
+
+#[clippy::msrv = "1.88.0"]
+fn msrv_ok_in_const() {
+ {
+ let c = Cell::new(42);
+ _ = c.get();
+ }
+ const {
+ let c = Cell::new(42);
+ _ = c.get();
+ }
+}
+
+#[clippy::msrv = "1.86.0"]
+fn enum_variant_not_ok() {
+ let _ = std::io::ErrorKind::InvalidFilename;
+ //~^ incompatible_msrv
+ let _ = const { std::io::ErrorKind::InvalidFilename };
+ //~^ incompatible_msrv
+}
+
+#[clippy::msrv = "1.87.0"]
+fn enum_variant_ok() {
+ let _ = std::io::ErrorKind::InvalidFilename;
+ let _ = const { std::io::ErrorKind::InvalidFilename };
}
fn main() {}
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.stderr b/src/tools/clippy/tests/ui/incompatible_msrv.stderr
index 5ea2bb9..e42360d 100644
--- a/src/tools/clippy/tests/ui/incompatible_msrv.stderr
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.stderr
@@ -1,5 +1,5 @@
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.10.0`
- --> tests/ui/incompatible_msrv.rs:14:39
+ --> tests/ui/incompatible_msrv.rs:16:39
|
LL | assert_eq!(map.entry("poneyland").key(), &"poneyland");
| ^^^^^
@@ -8,45 +8,107 @@
= help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.12.0`
- --> tests/ui/incompatible_msrv.rs:18:11
+ --> tests/ui/incompatible_msrv.rs:22:11
|
LL | v.into_key();
| ^^^^^^^^^^
error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`
- --> tests/ui/incompatible_msrv.rs:22:5
+ --> tests/ui/incompatible_msrv.rs:26:5
|
LL | sleep(Duration::new(1, 0));
| ^^^^^
-error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
- --> tests/ui/incompatible_msrv.rs:46:9
+error: current MSRV (Minimum Supported Rust Version) is `1.2.0` but this item is stable since `1.3.0`
+ --> tests/ui/incompatible_msrv.rs:31:33
|
-LL | core::panicking::panic("foo");
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | static NO_BODY_BAD_MSRV: Option<Duration> = None;
+ | ^^^^^^^^
-error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
- --> tests/ui/incompatible_msrv.rs:53:13
+error: current MSRV (Minimum Supported Rust Version) is `1.2.0` but this item is stable since `1.3.0`
+ --> tests/ui/incompatible_msrv.rs:38:19
|
-LL | core::panicking::panic($msg)
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | let _: Option<Duration> = None;
+ | ^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.43.0`
+ --> tests/ui/incompatible_msrv.rs:62:17
+ |
+LL | let _ = core::iter::once_with(|| 0);
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.43.0`
+ --> tests/ui/incompatible_msrv.rs:69:21
+ |
+LL | let _ = core::iter::once_with(|| $msg);
+ | ^^^^^^^^^^^^^^^^^^^^^
...
LL | my_panic!("foo");
| ---------------- in this macro invocation
|
= note: this error originates in the macro `my_panic` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
- --> tests/ui/incompatible_msrv.rs:59:13
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.43.0`
+ --> tests/ui/incompatible_msrv.rs:76:13
|
-LL | assert!(core::panicking::panic("out of luck"));
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | assert!(core::iter::once_with(|| 0).next().is_some());
+ | ^^^^^^^^^^^^^^^^^^^^^
error: current MSRV (Minimum Supported Rust Version) is `1.80.0` but this item is stable since `1.82.0`
- --> tests/ui/incompatible_msrv.rs:72:13
+ --> tests/ui/incompatible_msrv.rs:89:13
|
LL | let _ = std::iter::repeat_n((), 5);
| ^^^^^^^^^^^^^^^^^^^
-error: aborting due to 7 previous errors
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`
+ --> tests/ui/incompatible_msrv.rs:100:13
+ |
+LL | let _ = std::iter::repeat_n((), 5);
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`
+ --> tests/ui/incompatible_msrv.rs:105:17
+ |
+LL | let _ = std::iter::repeat_n((), 5);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: you may want to conditionally increase the MSRV considered by Clippy using the `clippy::msrv` attribute
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.82.0`
+ --> tests/ui/incompatible_msrv.rs:110:17
+ |
+LL | let _ = std::iter::repeat_n((), 5);
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.78.0` but this item is stable since `1.84.0`
+ --> tests/ui/incompatible_msrv.rs:123:7
+ |
+LL | r.isqrt()
+ | ^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.85.0`
+ --> tests/ui/incompatible_msrv.rs:128:13
+ |
+LL | let _ = std::io::ErrorKind::CrossesDevices;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.87.0` but this item is stable in a `const` context since `1.88.0`
+ --> tests/ui/incompatible_msrv.rs:140:15
+ |
+LL | _ = c.get();
+ | ^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.86.0` but this item is stable since `1.87.0`
+ --> tests/ui/incompatible_msrv.rs:159:13
+ |
+LL | let _ = std::io::ErrorKind::InvalidFilename;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.86.0` but this item is stable since `1.87.0`
+ --> tests/ui/incompatible_msrv.rs:161:21
+ |
+LL | let _ = const { std::io::ErrorKind::InvalidFilename };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 17 previous errors
diff --git a/src/tools/clippy/tests/ui/large_enum_variant.32bit.stderr b/src/tools/clippy/tests/ui/large_enum_variant.32bit.stderr
index 80ca5da..ac1ed27 100644
--- a/src/tools/clippy/tests/ui/large_enum_variant.32bit.stderr
+++ b/src/tools/clippy/tests/ui/large_enum_variant.32bit.stderr
@@ -12,7 +12,7 @@
|
= note: `-D clippy::large-enum-variant` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B([i32; 8000]),
LL + B(Box<[i32; 8000]>),
@@ -30,7 +30,7 @@
LL | | }
| |_^ the entire enum is at least 32004 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - ContainingLargeEnum(LargeEnum),
LL + ContainingLargeEnum(Box<LargeEnum>),
@@ -49,7 +49,7 @@
LL | | }
| |_^ the entire enum is at least 70008 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
LL + ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
@@ -67,7 +67,7 @@
LL | | }
| |_^ the entire enum is at least 32008 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - StructLikeLarge { x: [i32; 8000], y: i32 },
LL + StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
@@ -85,7 +85,7 @@
LL | | }
| |_^ the entire enum is at least 32004 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - StructLikeLarge2 { x: [i32; 8000] },
LL + StructLikeLarge2 { x: Box<[i32; 8000]> },
@@ -104,7 +104,7 @@
LL | | }
| |_^ the entire enum is at least 1256 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B([u8; 1255]),
LL + B(Box<[u8; 1255]>),
@@ -122,7 +122,7 @@
LL | | }
| |_^ the entire enum is at least 70132 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
LL + ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),
@@ -140,7 +140,7 @@
LL | | }
| |_^ the entire enum is at least 32004 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B(Struct2),
LL + B(Box<Struct2>),
@@ -158,7 +158,7 @@
LL | | }
| |_^ the entire enum is at least 32000 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B(Struct2),
LL + B(Box<Struct2>),
@@ -176,7 +176,7 @@
LL | | }
| |_^ the entire enum is at least 32000 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B(Struct2),
LL + B(Box<Struct2>),
@@ -199,7 +199,7 @@
|
LL | enum CopyableLargeEnum {
| ^^^^^^^^^^^^^^^^^
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
--> tests/ui/large_enum_variant.rs:118:5
|
LL | B([u64; 8000]),
@@ -222,7 +222,7 @@
|
LL | enum ManuallyCopyLargeEnum {
| ^^^^^^^^^^^^^^^^^^^^^
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
--> tests/ui/large_enum_variant.rs:124:5
|
LL | B([u64; 8000]),
@@ -245,7 +245,7 @@
|
LL | enum SomeGenericPossiblyCopyEnum<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
--> tests/ui/large_enum_variant.rs:138:5
|
LL | B([u64; 4000]),
@@ -263,7 +263,7 @@
LL | | }
| |_^ the entire enum is at least 512 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Large((T, [u8; 512])),
LL + Large(Box<(T, [u8; 512])>),
@@ -281,7 +281,7 @@
LL | | }
| |_^ the entire enum is at least 516 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Large([Foo<u64>; 64]),
LL + Large(Box<[Foo<u64>; 64]>),
@@ -299,7 +299,7 @@
LL | | }
| |_^ the entire enum is at least 514 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Error(PossiblyLargeEnumWithConst<256>),
LL + Error(Box<PossiblyLargeEnumWithConst<256>>),
@@ -317,7 +317,7 @@
LL | | }
| |_^ the entire enum is at least 516 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Large([u64; 64]),
LL + Large(Box<[u64; 64]>),
@@ -335,7 +335,7 @@
LL | | }
| |_^ the entire enum is at least 516 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Error(WithRecursionAndGenerics<u64>),
LL + Error(Box<WithRecursionAndGenerics<u64>>),
diff --git a/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr b/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr
index 559bdf2..d8199f9 100644
--- a/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr
+++ b/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr
@@ -12,7 +12,7 @@
|
= note: `-D clippy::large-enum-variant` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B([i32; 8000]),
LL + B(Box<[i32; 8000]>),
@@ -30,7 +30,7 @@
LL | | }
| |_^ the entire enum is at least 32004 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - ContainingLargeEnum(LargeEnum),
LL + ContainingLargeEnum(Box<LargeEnum>),
@@ -49,7 +49,7 @@
LL | | }
| |_^ the entire enum is at least 70008 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
LL + ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
@@ -67,7 +67,7 @@
LL | | }
| |_^ the entire enum is at least 32008 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - StructLikeLarge { x: [i32; 8000], y: i32 },
LL + StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
@@ -85,7 +85,7 @@
LL | | }
| |_^ the entire enum is at least 32004 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - StructLikeLarge2 { x: [i32; 8000] },
LL + StructLikeLarge2 { x: Box<[i32; 8000]> },
@@ -104,7 +104,7 @@
LL | | }
| |_^ the entire enum is at least 1256 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B([u8; 1255]),
LL + B(Box<[u8; 1255]>),
@@ -122,7 +122,7 @@
LL | | }
| |_^ the entire enum is at least 70132 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
LL + ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),
@@ -140,7 +140,7 @@
LL | | }
| |_^ the entire enum is at least 32004 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B(Struct2),
LL + B(Box<Struct2>),
@@ -158,7 +158,7 @@
LL | | }
| |_^ the entire enum is at least 32000 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B(Struct2),
LL + B(Box<Struct2>),
@@ -176,7 +176,7 @@
LL | | }
| |_^ the entire enum is at least 32000 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - B(Struct2),
LL + B(Box<Struct2>),
@@ -199,7 +199,7 @@
|
LL | enum CopyableLargeEnum {
| ^^^^^^^^^^^^^^^^^
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
--> tests/ui/large_enum_variant.rs:118:5
|
LL | B([u64; 8000]),
@@ -222,7 +222,7 @@
|
LL | enum ManuallyCopyLargeEnum {
| ^^^^^^^^^^^^^^^^^^^^^
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
--> tests/ui/large_enum_variant.rs:124:5
|
LL | B([u64; 8000]),
@@ -245,7 +245,7 @@
|
LL | enum SomeGenericPossiblyCopyEnum<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
--> tests/ui/large_enum_variant.rs:138:5
|
LL | B([u64; 4000]),
@@ -263,7 +263,7 @@
LL | | }
| |_^ the entire enum is at least 512 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Large((T, [u8; 512])),
LL + Large(Box<(T, [u8; 512])>),
@@ -281,7 +281,7 @@
LL | | }
| |_^ the entire enum is at least 520 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Large([Foo<u64>; 64]),
LL + Large(Box<[Foo<u64>; 64]>),
@@ -299,7 +299,7 @@
LL | | }
| |_^ the entire enum is at least 514 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Error(PossiblyLargeEnumWithConst<256>),
LL + Error(Box<PossiblyLargeEnumWithConst<256>>),
@@ -317,7 +317,7 @@
LL | | }
| |_^ the entire enum is at least 520 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Large([u64; 64]),
LL + Large(Box<[u64; 64]>),
@@ -335,7 +335,7 @@
LL | | }
| |_^ the entire enum is at least 520 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - Error(WithRecursionAndGenerics<u64>),
LL + Error(Box<WithRecursionAndGenerics<u64>>),
@@ -353,7 +353,7 @@
LL | | }
| |_____^ the entire enum is at least 296 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - BigBoi(PublishWithBytes),
LL + BigBoi(Box<PublishWithBytes>),
@@ -371,7 +371,7 @@
LL | | }
| |_____^ the entire enum is at least 224 bytes
|
-help: consider boxing the large fields to reduce the total size of the enum
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
|
LL - BigBoi(PublishWithVec),
LL + BigBoi(Box<PublishWithVec>),
diff --git a/src/tools/clippy/tests/ui/large_enum_variant_no_std.rs b/src/tools/clippy/tests/ui/large_enum_variant_no_std.rs
new file mode 100644
index 0000000..ff02131
--- /dev/null
+++ b/src/tools/clippy/tests/ui/large_enum_variant_no_std.rs
@@ -0,0 +1,8 @@
+#![no_std]
+#![warn(clippy::large_enum_variant)]
+
+enum Myenum {
+ //~^ ERROR: large size difference between variants
+ Small(u8),
+ Large([u8; 1024]),
+}
diff --git a/src/tools/clippy/tests/ui/large_enum_variant_no_std.stderr b/src/tools/clippy/tests/ui/large_enum_variant_no_std.stderr
new file mode 100644
index 0000000..4f32e3e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/large_enum_variant_no_std.stderr
@@ -0,0 +1,22 @@
+error: large size difference between variants
+ --> tests/ui/large_enum_variant_no_std.rs:4:1
+ |
+LL | / enum Myenum {
+LL | |
+LL | | Small(u8),
+ | | --------- the second-largest variant contains at least 1 bytes
+LL | | Large([u8; 1024]),
+ | | ----------------- the largest variant contains at least 1024 bytes
+LL | | }
+ | |_^ the entire enum is at least 1025 bytes
+ |
+help: consider boxing the large fields or introducing indirection in some other way to reduce the total size of the enum
+ --> tests/ui/large_enum_variant_no_std.rs:7:5
+ |
+LL | Large([u8; 1024]),
+ | ^^^^^^^^^^^^^^^^^
+ = note: `-D clippy::large-enum-variant` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed b/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed
index 30bb549..d90e7be 100644
--- a/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed
@@ -79,9 +79,31 @@
f64::consts::E;
b!();
+ std::primitive::i32::MAX;
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
[(0, "", i128::MAX)];
//~^ ERROR: usage of a legacy numeric constant
//~| HELP: use the associated constant instead
+ i32::MAX;
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
+ assert_eq!(0, -i32::MAX);
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
+ i128::MAX;
+ //~^ ERROR: usage of a legacy numeric constant
+ //~| HELP: use the associated constant instead
+ u32::MAX;
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
+ i32::MAX;
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
+ type Ω = i32;
+ Ω::MAX;
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
}
#[warn(clippy::legacy_numeric_constants)]
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.rs b/src/tools/clippy/tests/ui/legacy_numeric_constants.rs
index d387819..4a2ef3f 100644
--- a/src/tools/clippy/tests/ui/legacy_numeric_constants.rs
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.rs
@@ -79,9 +79,31 @@ fn main() {
f64::consts::E;
b!();
+ <std::primitive::i32>::max_value();
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
[(0, "", std::i128::MAX)];
//~^ ERROR: usage of a legacy numeric constant
//~| HELP: use the associated constant instead
+ (i32::max_value());
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
+ assert_eq!(0, -(i32::max_value()));
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
+ (std::i128::MAX);
+ //~^ ERROR: usage of a legacy numeric constant
+ //~| HELP: use the associated constant instead
+ (<u32>::max_value());
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
+ ((i32::max_value)());
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
+ type Ω = i32;
+ Ω::max_value();
+ //~^ ERROR: usage of a legacy numeric method
+ //~| HELP: use the associated constant instead
}
#[warn(clippy::legacy_numeric_constants)]
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr b/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr
index 4d69b81..0b4f32e 100644
--- a/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr
@@ -72,10 +72,10 @@
| +++++
error: usage of a legacy numeric method
- --> tests/ui/legacy_numeric_constants.rs:50:10
+ --> tests/ui/legacy_numeric_constants.rs:50:5
|
LL | i32::max_value();
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
|
help: use the associated constant instead
|
@@ -84,10 +84,10 @@
|
error: usage of a legacy numeric method
- --> tests/ui/legacy_numeric_constants.rs:53:9
+ --> tests/ui/legacy_numeric_constants.rs:53:5
|
LL | u8::max_value();
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^
|
help: use the associated constant instead
|
@@ -96,10 +96,10 @@
|
error: usage of a legacy numeric method
- --> tests/ui/legacy_numeric_constants.rs:56:9
+ --> tests/ui/legacy_numeric_constants.rs:56:5
|
LL | u8::min_value();
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^
|
help: use the associated constant instead
|
@@ -120,10 +120,10 @@
|
error: usage of a legacy numeric method
- --> tests/ui/legacy_numeric_constants.rs:62:27
+ --> tests/ui/legacy_numeric_constants.rs:62:5
|
LL | ::std::primitive::u8::min_value();
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use the associated constant instead
|
@@ -132,10 +132,10 @@
|
error: usage of a legacy numeric method
- --> tests/ui/legacy_numeric_constants.rs:65:26
+ --> tests/ui/legacy_numeric_constants.rs:65:5
|
LL | std::primitive::i32::max_value();
- | ^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use the associated constant instead
|
@@ -171,8 +171,20 @@
LL + let x = u64::MAX;
|
+error: usage of a legacy numeric method
+ --> tests/ui/legacy_numeric_constants.rs:82:5
+ |
+LL | <std::primitive::i32>::max_value();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: use the associated constant instead
+ |
+LL - <std::primitive::i32>::max_value();
+LL + std::primitive::i32::MAX;
+ |
+
error: usage of a legacy numeric constant
- --> tests/ui/legacy_numeric_constants.rs:82:14
+ --> tests/ui/legacy_numeric_constants.rs:85:14
|
LL | [(0, "", std::i128::MAX)];
| ^^^^^^^^^^^^^^
@@ -183,8 +195,80 @@
LL + [(0, "", i128::MAX)];
|
+error: usage of a legacy numeric method
+ --> tests/ui/legacy_numeric_constants.rs:88:5
+ |
+LL | (i32::max_value());
+ | ^^^^^^^^^^^^^^^^^^
+ |
+help: use the associated constant instead
+ |
+LL - (i32::max_value());
+LL + i32::MAX;
+ |
+
+error: usage of a legacy numeric method
+ --> tests/ui/legacy_numeric_constants.rs:91:20
+ |
+LL | assert_eq!(0, -(i32::max_value()));
+ | ^^^^^^^^^^^^^^^^^^
+ |
+help: use the associated constant instead
+ |
+LL - assert_eq!(0, -(i32::max_value()));
+LL + assert_eq!(0, -i32::MAX);
+ |
+
error: usage of a legacy numeric constant
- --> tests/ui/legacy_numeric_constants.rs:116:5
+ --> tests/ui/legacy_numeric_constants.rs:94:5
+ |
+LL | (std::i128::MAX);
+ | ^^^^^^^^^^^^^^^^
+ |
+help: use the associated constant instead
+ |
+LL - (std::i128::MAX);
+LL + i128::MAX;
+ |
+
+error: usage of a legacy numeric method
+ --> tests/ui/legacy_numeric_constants.rs:97:5
+ |
+LL | (<u32>::max_value());
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+help: use the associated constant instead
+ |
+LL - (<u32>::max_value());
+LL + u32::MAX;
+ |
+
+error: usage of a legacy numeric method
+ --> tests/ui/legacy_numeric_constants.rs:100:5
+ |
+LL | ((i32::max_value)());
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+help: use the associated constant instead
+ |
+LL - ((i32::max_value)());
+LL + i32::MAX;
+ |
+
+error: usage of a legacy numeric method
+ --> tests/ui/legacy_numeric_constants.rs:104:5
+ |
+LL | Ω::max_value();
+ | ^^^^^^^^^^^^^^
+ |
+help: use the associated constant instead
+ |
+LL - Ω::max_value();
+LL + Ω::MAX;
+ |
+
+error: usage of a legacy numeric constant
+ --> tests/ui/legacy_numeric_constants.rs:138:5
|
LL | std::u32::MAX;
| ^^^^^^^^^^^^^
@@ -195,5 +279,5 @@
LL + u32::MAX;
|
-error: aborting due to 16 previous errors
+error: aborting due to 23 previous errors
diff --git a/src/tools/clippy/tests/ui/manual_abs_diff.fixed b/src/tools/clippy/tests/ui/manual_abs_diff.fixed
index f1b1278..2766942 100644
--- a/src/tools/clippy/tests/ui/manual_abs_diff.fixed
+++ b/src/tools/clippy/tests/ui/manual_abs_diff.fixed
@@ -104,3 +104,7 @@
let (a, b) = (S(10), S(20));
let _ = if a < b { b - a } else { a - b };
}
+
+fn issue15254(a: &usize, b: &usize) -> usize {
+ b.abs_diff(*a)
+}
diff --git a/src/tools/clippy/tests/ui/manual_abs_diff.rs b/src/tools/clippy/tests/ui/manual_abs_diff.rs
index 60ef819..2c408f2 100644
--- a/src/tools/clippy/tests/ui/manual_abs_diff.rs
+++ b/src/tools/clippy/tests/ui/manual_abs_diff.rs
@@ -114,3 +114,12 @@ fn sub(self, rhs: Self) -> Self::Output {
let (a, b) = (S(10), S(20));
let _ = if a < b { b - a } else { a - b };
}
+
+fn issue15254(a: &usize, b: &usize) -> usize {
+ if a < b {
+ //~^ manual_abs_diff
+ b - a
+ } else {
+ a - b
+ }
+}
diff --git a/src/tools/clippy/tests/ui/manual_abs_diff.stderr b/src/tools/clippy/tests/ui/manual_abs_diff.stderr
index c14c1dc..bb6d312 100644
--- a/src/tools/clippy/tests/ui/manual_abs_diff.stderr
+++ b/src/tools/clippy/tests/ui/manual_abs_diff.stderr
@@ -79,5 +79,16 @@
LL | let _ = if a > b { (a - b) as u32 } else { (b - a) as u32 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `abs_diff`: `a.abs_diff(b)`
-error: aborting due to 11 previous errors
+error: manual absolute difference pattern without using `abs_diff`
+ --> tests/ui/manual_abs_diff.rs:119:5
+ |
+LL | / if a < b {
+LL | |
+LL | | b - a
+LL | | } else {
+LL | | a - b
+LL | | }
+ | |_____^ help: replace with `abs_diff`: `b.abs_diff(*a)`
+
+error: aborting due to 12 previous errors
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
index 8cedf2c..221cddf 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
@@ -189,5 +189,23 @@
LL + const BAR: () = assert!(!(N == 0), );
|
-error: aborting due to 10 previous errors
+error: only a `panic!` in `if`-then statement
+ --> tests/ui/manual_assert.rs:116:5
+ |
+LL | / if !is_x86_feature_detected!("ssse3") {
+LL | |
+LL | | panic!("SSSE3 is not supported");
+LL | | }
+ | |_____^
+ |
+help: try instead
+ |
+LL - if !is_x86_feature_detected!("ssse3") {
+LL -
+LL - panic!("SSSE3 is not supported");
+LL - }
+LL + assert!(is_x86_feature_detected!("ssse3"), "SSSE3 is not supported");
+ |
+
+error: aborting due to 11 previous errors
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
index 8cedf2c..221cddf 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
@@ -189,5 +189,23 @@
LL + const BAR: () = assert!(!(N == 0), );
|
-error: aborting due to 10 previous errors
+error: only a `panic!` in `if`-then statement
+ --> tests/ui/manual_assert.rs:116:5
+ |
+LL | / if !is_x86_feature_detected!("ssse3") {
+LL | |
+LL | | panic!("SSSE3 is not supported");
+LL | | }
+ | |_____^
+ |
+help: try instead
+ |
+LL - if !is_x86_feature_detected!("ssse3") {
+LL -
+LL - panic!("SSSE3 is not supported");
+LL - }
+LL + assert!(is_x86_feature_detected!("ssse3"), "SSSE3 is not supported");
+ |
+
+error: aborting due to 11 previous errors
diff --git a/src/tools/clippy/tests/ui/manual_assert.rs b/src/tools/clippy/tests/ui/manual_assert.rs
index 46a42c3..ab02bd5 100644
--- a/src/tools/clippy/tests/ui/manual_assert.rs
+++ b/src/tools/clippy/tests/ui/manual_assert.rs
@@ -105,3 +105,17 @@ impl<T, const N: usize> Foo<T, N> {
};
}
}
+
+fn issue15227(left: u64, right: u64) -> u64 {
+ macro_rules! is_x86_feature_detected {
+ ($feature:literal) => {
+ $feature.len() > 0 && $feature.starts_with("ss")
+ };
+ }
+
+ if !is_x86_feature_detected!("ssse3") {
+ //~^ manual_assert
+ panic!("SSSE3 is not supported");
+ }
+ unsafe { todo!() }
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_multiple_of.fixed b/src/tools/clippy/tests/ui/manual_is_multiple_of.fixed
index 6735b99..03f75e7 100644
--- a/src/tools/clippy/tests/ui/manual_is_multiple_of.fixed
+++ b/src/tools/clippy/tests/ui/manual_is_multiple_of.fixed
@@ -23,3 +23,81 @@
fn g(a: u64, b: u64) {
let _ = a % b == 0;
}
+
+fn needs_deref(a: &u64, b: &u64) {
+ let _ = a.is_multiple_of(*b); //~ manual_is_multiple_of
+}
+
+fn closures(a: u64, b: u64) {
+ // Do not lint, types are ambiguous at this point
+ let cl = |a, b| a % b == 0;
+ let _ = cl(a, b);
+
+ // Do not lint, types are ambiguous at this point
+ let cl = |a: _, b: _| a % b == 0;
+ let _ = cl(a, b);
+
+ // Type of `a` is enough
+ let cl = |a: u64, b| a.is_multiple_of(b); //~ manual_is_multiple_of
+ let _ = cl(a, b);
+
+ // Type of `a` is enough
+ let cl = |a: &u64, b| a.is_multiple_of(b); //~ manual_is_multiple_of
+ let _ = cl(&a, b);
+
+ // Type of `b` is not enough
+ let cl = |a, b: u64| a % b == 0;
+ let _ = cl(&a, b);
+}
+
+fn any_rem<T: std::ops::Rem<Output = u32>>(a: T, b: T) {
+ // An arbitrary `Rem` implementation should not lint
+ let _ = a % b == 0;
+}
+
+mod issue15103 {
+ fn foo() -> Option<u64> {
+ let mut n: u64 = 150_000_000;
+
+ (2..).find(|p| {
+ while n.is_multiple_of(*p) {
+ //~^ manual_is_multiple_of
+ n /= p;
+ }
+ n <= 1
+ })
+ }
+
+ const fn generate_primes<const N: usize>() -> [u64; N] {
+ let mut result = [0; N];
+ if N == 0 {
+ return result;
+ }
+ result[0] = 2;
+ if N == 1 {
+ return result;
+ }
+ let mut idx = 1;
+ let mut p = 3;
+ while idx < N {
+ let mut j = 0;
+ while j < idx && p % result[j] != 0 {
+ j += 1;
+ }
+ if j == idx {
+ result[idx] = p;
+ idx += 1;
+ }
+ p += 1;
+ }
+ result
+ }
+
+ fn bar() -> u32 {
+ let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n.is_multiple_of(*i)).sum() };
+ //~^ manual_is_multiple_of
+
+ let d = |n| (1..=n / 2).filter(|i| n % i == 0).sum();
+ (1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum()
+ }
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_multiple_of.rs b/src/tools/clippy/tests/ui/manual_is_multiple_of.rs
index 00b638e..7b6fa64 100644
--- a/src/tools/clippy/tests/ui/manual_is_multiple_of.rs
+++ b/src/tools/clippy/tests/ui/manual_is_multiple_of.rs
@@ -23,3 +23,81 @@ fn f(a: u64, b: u64) {
fn g(a: u64, b: u64) {
let _ = a % b == 0;
}
+
+fn needs_deref(a: &u64, b: &u64) {
+ let _ = a % b == 0; //~ manual_is_multiple_of
+}
+
+fn closures(a: u64, b: u64) {
+ // Do not lint, types are ambiguous at this point
+ let cl = |a, b| a % b == 0;
+ let _ = cl(a, b);
+
+ // Do not lint, types are ambiguous at this point
+ let cl = |a: _, b: _| a % b == 0;
+ let _ = cl(a, b);
+
+ // Type of `a` is enough
+ let cl = |a: u64, b| a % b == 0; //~ manual_is_multiple_of
+ let _ = cl(a, b);
+
+ // Type of `a` is enough
+ let cl = |a: &u64, b| a % b == 0; //~ manual_is_multiple_of
+ let _ = cl(&a, b);
+
+ // Type of `b` is not enough
+ let cl = |a, b: u64| a % b == 0;
+ let _ = cl(&a, b);
+}
+
+fn any_rem<T: std::ops::Rem<Output = u32>>(a: T, b: T) {
+ // An arbitrary `Rem` implementation should not lint
+ let _ = a % b == 0;
+}
+
+mod issue15103 {
+ fn foo() -> Option<u64> {
+ let mut n: u64 = 150_000_000;
+
+ (2..).find(|p| {
+ while n % p == 0 {
+ //~^ manual_is_multiple_of
+ n /= p;
+ }
+ n <= 1
+ })
+ }
+
+ const fn generate_primes<const N: usize>() -> [u64; N] {
+ let mut result = [0; N];
+ if N == 0 {
+ return result;
+ }
+ result[0] = 2;
+ if N == 1 {
+ return result;
+ }
+ let mut idx = 1;
+ let mut p = 3;
+ while idx < N {
+ let mut j = 0;
+ while j < idx && p % result[j] != 0 {
+ j += 1;
+ }
+ if j == idx {
+ result[idx] = p;
+ idx += 1;
+ }
+ p += 1;
+ }
+ result
+ }
+
+ fn bar() -> u32 {
+ let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n % i == 0).sum() };
+ //~^ manual_is_multiple_of
+
+ let d = |n| (1..=n / 2).filter(|i| n % i == 0).sum();
+ (1..1_000).filter(|&i| i == d(d(i)) && i != d(i)).sum()
+ }
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_multiple_of.stderr b/src/tools/clippy/tests/ui/manual_is_multiple_of.stderr
index 0b1ae70..8523599 100644
--- a/src/tools/clippy/tests/ui/manual_is_multiple_of.stderr
+++ b/src/tools/clippy/tests/ui/manual_is_multiple_of.stderr
@@ -37,5 +37,35 @@
LL | let _ = 0 < a % b;
| ^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)`
-error: aborting due to 6 previous errors
+error: manual implementation of `.is_multiple_of()`
+ --> tests/ui/manual_is_multiple_of.rs:28:13
+ |
+LL | let _ = a % b == 0;
+ | ^^^^^^^^^^ help: replace with: `a.is_multiple_of(*b)`
+
+error: manual implementation of `.is_multiple_of()`
+ --> tests/ui/manual_is_multiple_of.rs:41:26
+ |
+LL | let cl = |a: u64, b| a % b == 0;
+ | ^^^^^^^^^^ help: replace with: `a.is_multiple_of(b)`
+
+error: manual implementation of `.is_multiple_of()`
+ --> tests/ui/manual_is_multiple_of.rs:45:27
+ |
+LL | let cl = |a: &u64, b| a % b == 0;
+ | ^^^^^^^^^^ help: replace with: `a.is_multiple_of(b)`
+
+error: manual implementation of `.is_multiple_of()`
+ --> tests/ui/manual_is_multiple_of.rs:63:19
+ |
+LL | while n % p == 0 {
+ | ^^^^^^^^^^ help: replace with: `n.is_multiple_of(*p)`
+
+error: manual implementation of `.is_multiple_of()`
+ --> tests/ui/manual_is_multiple_of.rs:97:58
+ |
+LL | let d = |n: u32| -> u32 { (1..=n / 2).filter(|i| n % i == 0).sum() };
+ | ^^^^^^^^^^ help: replace with: `n.is_multiple_of(*i)`
+
+error: aborting due to 11 previous errors
diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed
index 83b2dac..b82d3e6 100644
--- a/src/tools/clippy/tests/ui/map_identity.fixed
+++ b/src/tools/clippy/tests/ui/map_identity.fixed
@@ -87,3 +87,15 @@
let _ = { it }.next();
//~^ map_identity
}
+
+// same as `issue11764`, but for arrays
+fn issue15198() {
+ let x = [[1, 2], [3, 4]];
+ // don't lint: `&[i32; 2]` becomes `[&i32; 2]`
+ let _ = x.iter().map(|[x, y]| [x, y]);
+ let _ = x.iter().map(|x| [x[0]]).map(|[x]| x);
+
+ // no match ergonomics for `[i32, i32]`
+ let _ = x.iter().copied();
+ //~^ map_identity
+}
diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs
index e839c55..c295bf8 100644
--- a/src/tools/clippy/tests/ui/map_identity.rs
+++ b/src/tools/clippy/tests/ui/map_identity.rs
@@ -93,3 +93,15 @@ fn issue13904() {
let _ = { it }.map(|x| x).next();
//~^ map_identity
}
+
+// same as `issue11764`, but for arrays
+fn issue15198() {
+ let x = [[1, 2], [3, 4]];
+ // don't lint: `&[i32; 2]` becomes `[&i32; 2]`
+ let _ = x.iter().map(|[x, y]| [x, y]);
+ let _ = x.iter().map(|x| [x[0]]).map(|[x]| x);
+
+ // no match ergonomics for `[i32, i32]`
+ let _ = x.iter().copied().map(|[x, y]| [x, y]);
+ //~^ map_identity
+}
diff --git a/src/tools/clippy/tests/ui/map_identity.stderr b/src/tools/clippy/tests/ui/map_identity.stderr
index 9836f3b..9b624a0 100644
--- a/src/tools/clippy/tests/ui/map_identity.stderr
+++ b/src/tools/clippy/tests/ui/map_identity.stderr
@@ -87,5 +87,11 @@
LL | let _ = { it }.map(|x| x).next();
| ^^^^^^^^^^^ help: remove the call to `map`
-error: aborting due to 13 previous errors
+error: unnecessary map of the identity function
+ --> tests/ui/map_identity.rs:105:30
+ |
+LL | let _ = x.iter().copied().map(|[x, y]| [x, y]);
+ | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
+
+error: aborting due to 14 previous errors
diff --git a/src/tools/clippy/tests/ui/missing_inline.rs b/src/tools/clippy/tests/ui/missing_inline.rs
index c180100..223c744 100644
--- a/src/tools/clippy/tests/ui/missing_inline.rs
+++ b/src/tools/clippy/tests/ui/missing_inline.rs
@@ -80,3 +80,20 @@ pub fn PubFooImpl() {}
// do not lint this since users cannot control the external code
#[derive(Debug)]
pub struct S;
+
+pub mod issue15301 {
+ #[unsafe(no_mangle)]
+ pub extern "C" fn call_from_c() {
+ println!("Just called a Rust function from C!");
+ }
+
+ #[unsafe(no_mangle)]
+ pub extern "Rust" fn call_from_rust() {
+ println!("Just called a Rust function from Rust!");
+ }
+
+ #[unsafe(no_mangle)]
+ pub fn call_from_rust_no_extern() {
+ println!("Just called a Rust function from Rust!");
+ }
+}
diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.rs b/src/tools/clippy/tests/ui/module_name_repetitions.rs
index 2fde98d..5d16858 100644
--- a/src/tools/clippy/tests/ui/module_name_repetitions.rs
+++ b/src/tools/clippy/tests/ui/module_name_repetitions.rs
@@ -55,3 +55,21 @@ pub trait TryFromFoo {}
}
fn main() {}
+
+pub mod issue14095 {
+ pub mod widget {
+ #[macro_export]
+ macro_rules! define_widget {
+ ($id:ident) => {
+ /* ... */
+ };
+ }
+
+ #[macro_export]
+ macro_rules! widget_impl {
+ ($id:ident) => {
+ /* ... */
+ };
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.fixed b/src/tools/clippy/tests/ui/must_use_candidates.fixed
index 4c1d6b1..1e8589c 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.fixed
+++ b/src/tools/clippy/tests/ui/must_use_candidates.fixed
@@ -13,13 +13,15 @@
pub struct MyAtomic(AtomicBool);
pub struct MyPure;
-#[must_use] pub fn pure(i: u8) -> u8 {
+#[must_use]
+pub fn pure(i: u8) -> u8 {
//~^ must_use_candidate
i
}
impl MyPure {
- #[must_use] pub fn inherent_pure(&self) -> u8 {
+ #[must_use]
+ pub fn inherent_pure(&self) -> u8 {
//~^ must_use_candidate
0
}
@@ -51,7 +53,8 @@
f(0)
}
-#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {
+#[must_use]
+pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {
//~^ must_use_candidate
true
}
@@ -64,7 +67,8 @@
b.load(Ordering::SeqCst)
}
-#[must_use] pub fn rcd(_x: Rc<u32>) -> bool {
+#[must_use]
+pub fn rcd(_x: Rc<u32>) -> bool {
//~^ must_use_candidate
true
}
@@ -73,7 +77,8 @@
true
}
-#[must_use] pub fn arcd(_x: Arc<u32>) -> bool {
+#[must_use]
+pub fn arcd(_x: Arc<u32>) -> bool {
//~^ must_use_candidate
false
}
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.stderr b/src/tools/clippy/tests/ui/must_use_candidates.stderr
index 590253d..5ddbd02 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.stderr
+++ b/src/tools/clippy/tests/ui/must_use_candidates.stderr
@@ -1,35 +1,64 @@
error: this function could have a `#[must_use]` attribute
- --> tests/ui/must_use_candidates.rs:16:1
+ --> tests/ui/must_use_candidates.rs:16:8
|
LL | pub fn pure(i: u8) -> u8 {
- | ^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn pure(i: u8) -> u8`
+ | ^^^^
|
= note: `-D clippy::must-use-candidate` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::must_use_candidate)]`
+help: add the attribute
+ |
+LL + #[must_use]
+LL | pub fn pure(i: u8) -> u8 {
+ |
error: this method could have a `#[must_use]` attribute
- --> tests/ui/must_use_candidates.rs:22:5
+ --> tests/ui/must_use_candidates.rs:22:12
|
LL | pub fn inherent_pure(&self) -> u8 {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8`
+ | ^^^^^^^^^^^^^
+ |
+help: add the attribute
+ |
+LL ~ #[must_use]
+LL ~ pub fn inherent_pure(&self) -> u8 {
+ |
error: this function could have a `#[must_use]` attribute
- --> tests/ui/must_use_candidates.rs:54:1
+ --> tests/ui/must_use_candidates.rs:54:8
|
LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool`
+ | ^^^^^^^^^^^
+ |
+help: add the attribute
+ |
+LL + #[must_use]
+LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {
+ |
error: this function could have a `#[must_use]` attribute
- --> tests/ui/must_use_candidates.rs:67:1
+ --> tests/ui/must_use_candidates.rs:67:8
|
LL | pub fn rcd(_x: Rc<u32>) -> bool {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc<u32>) -> bool`
+ | ^^^
+ |
+help: add the attribute
+ |
+LL + #[must_use]
+LL | pub fn rcd(_x: Rc<u32>) -> bool {
+ |
error: this function could have a `#[must_use]` attribute
- --> tests/ui/must_use_candidates.rs:76:1
+ --> tests/ui/must_use_candidates.rs:76:8
|
LL | pub fn arcd(_x: Arc<u32>) -> bool {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc<u32>) -> bool`
+ | ^^^^
+ |
+help: add the attribute
+ |
+LL + #[must_use]
+LL | pub fn arcd(_x: Arc<u32>) -> bool {
+ |
error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
index a73aff5..a6d64d9 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
@@ -143,3 +143,9 @@
//~^ needless_for_each
}
}
+
+fn issue15256() {
+ let vec: Vec<i32> = Vec::new();
+ for v in vec.iter() { println!("{v}"); }
+ //~^ needless_for_each
+}
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
index d92f055..7e74d2b 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
@@ -143,3 +143,9 @@ fn single_expr(rows: &[u8]) {
//~^ needless_for_each
}
}
+
+fn issue15256() {
+ let vec: Vec<i32> = Vec::new();
+ vec.iter().for_each(|v| println!("{v}"));
+ //~^ needless_for_each
+}
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
index f801445..204cfa3 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
@@ -148,5 +148,11 @@
LL | rows.iter().for_each(|x| do_something(x, 1u8));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in rows.iter() { do_something(x, 1u8); }`
-error: aborting due to 10 previous errors
+error: needless use of `for_each`
+ --> tests/ui/needless_for_each_fixable.rs:149:5
+ |
+LL | vec.iter().for_each(|v| println!("{v}"));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec.iter() { println!("{v}"); }`
+
+error: aborting due to 11 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_range_loop.rs b/src/tools/clippy/tests/ui/needless_range_loop.rs
index 8a1c1be..70cf9fa 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop.rs
+++ b/src/tools/clippy/tests/ui/needless_range_loop.rs
@@ -185,3 +185,28 @@ pub fn test<H: Handle>() -> H {
unimplemented!()
}
}
+
+fn needless_loop() {
+ use std::hint::black_box;
+ let x = [0; 64];
+ for i in 0..64 {
+ let y = [0; 64];
+
+ black_box(x[i]);
+ black_box(y[i]);
+ }
+
+ for i in 0..64 {
+ black_box(x[i]);
+ black_box([0; 64][i]);
+ }
+
+ for i in 0..64 {
+ black_box(x[i]);
+ black_box([1, 2, 3, 4, 5, 6, 7, 8][i]);
+ }
+
+ for i in 0..64 {
+ black_box([1, 2, 3, 4, 5, 6, 7, 8][i]);
+ }
+}
diff --git a/src/tools/clippy/tests/ui/never_loop.rs b/src/tools/clippy/tests/ui/never_loop.rs
index e0f54ef..48d4b8a 100644
--- a/src/tools/clippy/tests/ui/never_loop.rs
+++ b/src/tools/clippy/tests/ui/never_loop.rs
@@ -466,3 +466,35 @@ fn main() {
test13();
test14();
}
+
+fn issue15059() {
+ 'a: for _ in 0..1 {
+ //~^ never_loop
+ break 'a;
+ }
+
+ let mut b = 1;
+ 'a: for i in 0..1 {
+ //~^ never_loop
+ match i {
+ 0 => {
+ b *= 2;
+ break 'a;
+ },
+ x => {
+ b += x;
+ break 'a;
+ },
+ }
+ }
+
+ #[allow(clippy::unused_unit)]
+ for v in 0..10 {
+ //~^ never_loop
+ break;
+ println!("{v}");
+ // This is comment and should be kept
+ println!("This is a comment");
+ ()
+ }
+}
diff --git a/src/tools/clippy/tests/ui/never_loop.stderr b/src/tools/clippy/tests/ui/never_loop.stderr
index bc9a7ec..54b4632 100644
--- a/src/tools/clippy/tests/ui/never_loop.stderr
+++ b/src/tools/clippy/tests/ui/never_loop.stderr
@@ -176,8 +176,10 @@
|
help: if you need the first element of the iterator, try writing
|
-LL - for v in 0..10 {
-LL + if let Some(v) = (0..10).next() {
+LL ~ if let Some(v) = (0..10).next() {
+LL |
+LL ~
+LL ~
|
error: this loop never actually loops
@@ -232,5 +234,68 @@
LL | | }
| |_________^
-error: aborting due to 21 previous errors
+error: this loop never actually loops
+ --> tests/ui/never_loop.rs:471:5
+ |
+LL | / 'a: for _ in 0..1 {
+LL | |
+LL | | break 'a;
+LL | | }
+ | |_____^
+ |
+help: if you need the first element of the iterator, try writing
+ |
+LL ~ if let Some(_) = (0..1).next() {
+LL |
+LL ~
+ |
+
+error: this loop never actually loops
+ --> tests/ui/never_loop.rs:477:5
+ |
+LL | / 'a: for i in 0..1 {
+LL | |
+LL | | match i {
+LL | | 0 => {
+... |
+LL | | }
+ | |_____^
+ |
+help: if you need the first element of the iterator, try writing
+ |
+LL ~ if let Some(i) = (0..1).next() {
+LL |
+...
+LL | b *= 2;
+LL ~
+LL | },
+LL | x => {
+LL | b += x;
+LL ~
+ |
+
+error: this loop never actually loops
+ --> tests/ui/never_loop.rs:492:5
+ |
+LL | / for v in 0..10 {
+LL | |
+LL | | break;
+LL | | println!("{v}");
+... |
+LL | | ()
+LL | | }
+ | |_____^
+ |
+help: if you need the first element of the iterator, try writing
+ |
+LL ~ if let Some(v) = (0..10).next() {
+LL |
+LL ~
+LL ~
+LL | // This is comment and should be kept
+LL ~
+LL ~
+ |
+
+error: aborting due to 24 previous errors
diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed
index bcd2602..0a8525a 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/or_fun_call.fixed
@@ -283,6 +283,8 @@
let _ = Some(4).map_or_else(g, f);
//~^ or_fun_call
let _ = Some(4).map_or(0, f);
+ let _ = Some(4).map_or_else(|| "asd".to_string().len() as i32, f);
+ //~^ or_fun_call
}
}
@@ -426,6 +428,8 @@
let _ = x.map_or_else(|_| g(), f);
//~^ or_fun_call
let _ = x.map_or(0, f);
+ let _ = x.map_or_else(|_| "asd".to_string().len() as i32, f);
+ //~^ or_fun_call
}
}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs
index 8d1202e..b4f9b95 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.rs
+++ b/src/tools/clippy/tests/ui/or_fun_call.rs
@@ -283,6 +283,8 @@ fn test_map_or() {
let _ = Some(4).map_or(g(), f);
//~^ or_fun_call
let _ = Some(4).map_or(0, f);
+ let _ = Some(4).map_or("asd".to_string().len() as i32, f);
+ //~^ or_fun_call
}
}
@@ -426,6 +428,8 @@ fn test_map_or() {
let _ = x.map_or(g(), f);
//~^ or_fun_call
let _ = x.map_or(0, f);
+ let _ = x.map_or("asd".to_string().len() as i32, f);
+ //~^ or_fun_call
}
}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr
index 585ee2d..3e4df77 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/or_fun_call.stderr
@@ -154,62 +154,68 @@
LL | let _ = Some(4).map_or(g(), f);
| ^^^^^^^^^^^^^^ help: try: `map_or_else(g, f)`
+error: function call inside of `map_or`
+ --> tests/ui/or_fun_call.rs:286:25
+ |
+LL | let _ = Some(4).map_or("asd".to_string().len() as i32, f);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| "asd".to_string().len() as i32, f)`
+
error: use of `unwrap_or_else` to construct default value
- --> tests/ui/or_fun_call.rs:315:18
+ --> tests/ui/or_fun_call.rs:317:18
|
LL | with_new.unwrap_or_else(Vec::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> tests/ui/or_fun_call.rs:319:28
+ --> tests/ui/or_fun_call.rs:321:28
|
LL | with_default_trait.unwrap_or_else(Default::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> tests/ui/or_fun_call.rs:323:27
+ --> tests/ui/or_fun_call.rs:325:27
|
LL | with_default_type.unwrap_or_else(u64::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `unwrap_or_else` to construct default value
- --> tests/ui/or_fun_call.rs:327:22
+ --> tests/ui/or_fun_call.rs:329:22
|
LL | real_default.unwrap_or_else(<FakeDefault as Default>::default);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: use of `or_insert_with` to construct default value
- --> tests/ui/or_fun_call.rs:331:23
+ --> tests/ui/or_fun_call.rs:333:23
|
LL | map.entry(42).or_insert_with(String::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
error: use of `or_insert_with` to construct default value
- --> tests/ui/or_fun_call.rs:335:25
+ --> tests/ui/or_fun_call.rs:337:25
|
LL | btree.entry(42).or_insert_with(String::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `or_default()`
error: use of `unwrap_or_else` to construct default value
- --> tests/ui/or_fun_call.rs:339:25
+ --> tests/ui/or_fun_call.rs:341:25
|
LL | let _ = stringy.unwrap_or_else(String::new);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: function call inside of `unwrap_or`
- --> tests/ui/or_fun_call.rs:381:17
+ --> tests/ui/or_fun_call.rs:383:17
|
LL | let _ = opt.unwrap_or({ f() }); // suggest `.unwrap_or_else(f)`
| ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(f)`
error: function call inside of `unwrap_or`
- --> tests/ui/or_fun_call.rs:386:17
+ --> tests/ui/or_fun_call.rs:388:17
|
LL | let _ = opt.unwrap_or(f() + 1); // suggest `.unwrap_or_else(|| f() + 1)`
| ^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| f() + 1)`
error: function call inside of `unwrap_or`
- --> tests/ui/or_fun_call.rs:391:17
+ --> tests/ui/or_fun_call.rs:393:17
|
LL | let _ = opt.unwrap_or({
| _________________^
@@ -229,52 +235,58 @@
|
error: function call inside of `map_or`
- --> tests/ui/or_fun_call.rs:397:17
+ --> tests/ui/or_fun_call.rs:399:17
|
LL | let _ = opt.map_or(f() + 1, |v| v); // suggest `.map_or_else(|| f() + 1, |v| v)`
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|| f() + 1, |v| v)`
error: use of `unwrap_or` to construct default value
- --> tests/ui/or_fun_call.rs:402:17
+ --> tests/ui/or_fun_call.rs:404:17
|
LL | let _ = opt.unwrap_or({ i32::default() });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_default()`
error: function call inside of `unwrap_or`
- --> tests/ui/or_fun_call.rs:409:21
+ --> tests/ui/or_fun_call.rs:411:21
|
LL | let _ = opt_foo.unwrap_or(Foo { val: String::default() });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| Foo { val: String::default() })`
error: function call inside of `map_or`
- --> tests/ui/or_fun_call.rs:424:19
+ --> tests/ui/or_fun_call.rs:426:19
|
LL | let _ = x.map_or(g(), |v| v);
| ^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), |v| v)`
error: function call inside of `map_or`
- --> tests/ui/or_fun_call.rs:426:19
+ --> tests/ui/or_fun_call.rs:428:19
|
LL | let _ = x.map_or(g(), f);
| ^^^^^^^^^^^^^^ help: try: `map_or_else(|_| g(), f)`
+error: function call inside of `map_or`
+ --> tests/ui/or_fun_call.rs:431:19
+ |
+LL | let _ = x.map_or("asd".to_string().len() as i32, f);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map_or_else(|_| "asd".to_string().len() as i32, f)`
+
error: function call inside of `get_or_insert`
- --> tests/ui/or_fun_call.rs:438:15
+ --> tests/ui/or_fun_call.rs:442:15
|
LL | let _ = x.get_or_insert(g());
| ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)`
error: function call inside of `and`
- --> tests/ui/or_fun_call.rs:448:15
+ --> tests/ui/or_fun_call.rs:452:15
|
LL | let _ = x.and(g());
| ^^^^^^^^ help: try: `and_then(|_| g())`
error: function call inside of `and`
- --> tests/ui/or_fun_call.rs:458:15
+ --> tests/ui/or_fun_call.rs:462:15
|
LL | let _ = x.and(g());
| ^^^^^^^^ help: try: `and_then(|_| g())`
-error: aborting due to 43 previous errors
+error: aborting due to 45 previous errors
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/auxiliary/external.rs b/src/tools/clippy/tests/ui/pattern_type_mismatch/auxiliary/external.rs
new file mode 100644
index 0000000..cd27c5c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/auxiliary/external.rs
@@ -0,0 +1,13 @@
+//! **FAKE** external macro crate.
+
+#[macro_export]
+macro_rules! macro_with_match {
+ ( $p:pat ) => {
+ let something = ();
+
+ match &something {
+ $p => true,
+ _ => false,
+ }
+ };
+}
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs
index 49ea1d3..aa988a5 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.rs
@@ -6,6 +6,9 @@
clippy::single_match
)]
+//@aux-build:external.rs
+use external::macro_with_match;
+
fn main() {}
fn syntax_match() {
@@ -159,3 +162,9 @@ macro_rules! matching_macro {
let value = &Some(23);
matching_macro!(value);
}
+
+fn external_macro_expansion() {
+ macro_with_match! {
+ ()
+ };
+}
diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
index cd604d6..636841e 100644
--- a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
+++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr
@@ -1,5 +1,5 @@
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:16:9
+ --> tests/ui/pattern_type_mismatch/syntax.rs:19:9
|
LL | Some(_) => (),
| ^^^^^^^
@@ -9,7 +9,7 @@
= help: to override `-D warnings` add `#[allow(clippy::pattern_type_mismatch)]`
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:36:12
+ --> tests/ui/pattern_type_mismatch/syntax.rs:39:12
|
LL | if let Some(_) = ref_value {}
| ^^^^^^^
@@ -17,7 +17,7 @@
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:48:15
+ --> tests/ui/pattern_type_mismatch/syntax.rs:51:15
|
LL | while let Some(_) = ref_value {
| ^^^^^^^
@@ -25,7 +25,7 @@
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:68:9
+ --> tests/ui/pattern_type_mismatch/syntax.rs:71:9
|
LL | for (_a, _b) in slice.iter() {}
| ^^^^^^^^
@@ -33,7 +33,7 @@
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:79:9
+ --> tests/ui/pattern_type_mismatch/syntax.rs:82:9
|
LL | let (_n, _m) = ref_value;
| ^^^^^^^^
@@ -41,7 +41,7 @@
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:89:12
+ --> tests/ui/pattern_type_mismatch/syntax.rs:92:12
|
LL | fn foo((_a, _b): &(i32, i32)) {}
| ^^^^^^^^
@@ -49,7 +49,7 @@
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:104:10
+ --> tests/ui/pattern_type_mismatch/syntax.rs:107:10
|
LL | foo(|(_a, _b)| ());
| ^^^^^^^^
@@ -57,7 +57,7 @@
= help: explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:121:9
+ --> tests/ui/pattern_type_mismatch/syntax.rs:124:9
|
LL | Some(_) => (),
| ^^^^^^^
@@ -65,7 +65,7 @@
= help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings
error: type of pattern does not match the expression type
- --> tests/ui/pattern_type_mismatch/syntax.rs:142:17
+ --> tests/ui/pattern_type_mismatch/syntax.rs:145:17
|
LL | Some(_) => (),
| ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs
index 578641e..be14e07 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.rs
+++ b/src/tools/clippy/tests/ui/ptr_arg.rs
@@ -123,7 +123,7 @@ fn test_cow_with_ref(c: &Cow<[i32]>) {}
//~^ ptr_arg
fn test_cow(c: Cow<[i32]>) {
- let _c = c;
+ let d = c;
}
trait Foo2 {
@@ -141,36 +141,36 @@ mod issue_5644 {
use std::path::PathBuf;
fn allowed(
- #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
- #[allow(clippy::ptr_arg)] _s: &String,
- #[allow(clippy::ptr_arg)] _p: &PathBuf,
- #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
- #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
+ #[allow(clippy::ptr_arg)] v: &Vec<u32>,
+ #[allow(clippy::ptr_arg)] s: &String,
+ #[allow(clippy::ptr_arg)] p: &PathBuf,
+ #[allow(clippy::ptr_arg)] c: &Cow<[i32]>,
+ #[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,
) {
}
- fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
+ fn some_allowed(#[allow(clippy::ptr_arg)] v: &Vec<u32>, s: &String) {}
//~^ ptr_arg
struct S;
impl S {
fn allowed(
- #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
- #[allow(clippy::ptr_arg)] _s: &String,
- #[allow(clippy::ptr_arg)] _p: &PathBuf,
- #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
- #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
+ #[allow(clippy::ptr_arg)] v: &Vec<u32>,
+ #[allow(clippy::ptr_arg)] s: &String,
+ #[allow(clippy::ptr_arg)] p: &PathBuf,
+ #[allow(clippy::ptr_arg)] c: &Cow<[i32]>,
+ #[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,
) {
}
}
trait T {
fn allowed(
- #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
- #[allow(clippy::ptr_arg)] _s: &String,
- #[allow(clippy::ptr_arg)] _p: &PathBuf,
- #[allow(clippy::ptr_arg)] _c: &Cow<[i32]>,
- #[expect(clippy::ptr_arg)] _expect: &Cow<[i32]>,
+ #[allow(clippy::ptr_arg)] v: &Vec<u32>,
+ #[allow(clippy::ptr_arg)] s: &String,
+ #[allow(clippy::ptr_arg)] p: &PathBuf,
+ #[allow(clippy::ptr_arg)] c: &Cow<[i32]>,
+ #[expect(clippy::ptr_arg)] expect: &Cow<[i32]>,
) {
}
}
@@ -182,22 +182,22 @@ mod issue6509 {
fn foo_vec(vec: &Vec<u8>) {
//~^ ptr_arg
- let _ = vec.clone().pop();
- let _ = vec.clone().clone();
+ let a = vec.clone().pop();
+ let b = vec.clone().clone();
}
fn foo_path(path: &PathBuf) {
//~^ ptr_arg
- let _ = path.clone().pop();
- let _ = path.clone().clone();
+ let c = path.clone().pop();
+ let d = path.clone().clone();
}
- fn foo_str(str: &PathBuf) {
+ fn foo_str(str: &String) {
//~^ ptr_arg
- let _ = str.clone().pop();
- let _ = str.clone().clone();
+ let e = str.clone().pop();
+ let f = str.clone().clone();
}
}
@@ -340,8 +340,8 @@ fn repro2(source: &str, destination: &mut String) {
ToOwned::clone_into(source, destination);
}
- fn h1(_: &<String as Deref>::Target) {}
- fn h2<T: Deref>(_: T, _: &T::Target) {}
+ fn h1(x: &<String as Deref>::Target) {}
+ fn h2<T: Deref>(x: T, y: &T::Target) {}
// Other cases that are still ok to lint and ideally shouldn't regress
fn good(v1: &String, v2: &String) {
@@ -352,3 +352,91 @@ fn good(v1: &String, v2: &String) {
h2(String::new(), v2);
}
}
+
+mod issue_13489_and_13728 {
+ // This is a no-lint from now on.
+ fn foo(_x: &Vec<i32>) {
+ todo!();
+ }
+
+ // But this still gives us a lint.
+ fn foo_used(x: &Vec<i32>) {
+ //~^ ptr_arg
+
+ todo!();
+ }
+
+ // This is also a no-lint from now on.
+ fn foo_local(x: &Vec<i32>) {
+ let _y = x;
+
+ todo!();
+ }
+
+ // But this still gives us a lint.
+ fn foo_local_used(x: &Vec<i32>) {
+ //~^ ptr_arg
+
+ let y = x;
+
+ todo!();
+ }
+
+ // This only lints once from now on.
+ fn foofoo(_x: &Vec<i32>, y: &String) {
+ //~^ ptr_arg
+
+ todo!();
+ }
+
+ // And this is also a no-lint from now on.
+ fn foofoo_local(_x: &Vec<i32>, y: &String) {
+ let _z = y;
+
+ todo!();
+ }
+}
+
+mod issue_13489_and_13728_mut {
+ // This is a no-lint from now on.
+ fn bar(_x: &mut Vec<u32>) {
+ todo!()
+ }
+
+ // But this still gives us a lint.
+ fn bar_used(x: &mut Vec<u32>) {
+ //~^ ptr_arg
+
+ todo!()
+ }
+
+ // This is also a no-lint from now on.
+ fn bar_local(x: &mut Vec<u32>) {
+ let _y = x;
+
+ todo!()
+ }
+
+ // But this still gives us a lint.
+ fn bar_local_used(x: &mut Vec<u32>) {
+ //~^ ptr_arg
+
+ let y = x;
+
+ todo!()
+ }
+
+ // This only lints once from now on.
+ fn barbar(_x: &mut Vec<u32>, y: &mut String) {
+ //~^ ptr_arg
+
+ todo!()
+ }
+
+ // And this is also a no-lint from now on.
+ fn barbar_local(_x: &mut Vec<u32>, y: &mut String) {
+ let _z = y;
+
+ todo!()
+ }
+}
diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr
index fd9cedd..8723505 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.stderr
+++ b/src/tools/clippy/tests/ui/ptr_arg.stderr
@@ -127,10 +127,10 @@
| ^^^^^^^^^^^ help: change this to: `&[i32]`
error: writing `&String` instead of `&str` involves a new object where a slice will do
- --> tests/ui/ptr_arg.rs:152:66
+ --> tests/ui/ptr_arg.rs:152:64
|
-LL | fn some_allowed(#[allow(clippy::ptr_arg)] _v: &Vec<u32>, _s: &String) {}
- | ^^^^^^^ help: change this to: `&str`
+LL | fn some_allowed(#[allow(clippy::ptr_arg)] v: &Vec<u32>, s: &String) {}
+ | ^^^^^^^ help: change this to: `&str`
error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
--> tests/ui/ptr_arg.rs:182:21
@@ -143,8 +143,8 @@
LL ~ fn foo_vec(vec: &[u8]) {
LL |
LL |
-LL ~ let _ = vec.to_owned().pop();
-LL ~ let _ = vec.to_owned().clone();
+LL ~ let a = vec.to_owned().pop();
+LL ~ let b = vec.to_owned().clone();
|
error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
@@ -158,23 +158,23 @@
LL ~ fn foo_path(path: &Path) {
LL |
LL |
-LL ~ let _ = path.to_path_buf().pop();
-LL ~ let _ = path.to_path_buf().clone();
+LL ~ let c = path.to_path_buf().pop();
+LL ~ let d = path.to_path_buf().clone();
|
-error: writing `&PathBuf` instead of `&Path` involves a new object where a slice will do
+error: writing `&String` instead of `&str` involves a new object where a slice will do
--> tests/ui/ptr_arg.rs:196:21
|
-LL | fn foo_str(str: &PathBuf) {
- | ^^^^^^^^
+LL | fn foo_str(str: &String) {
+ | ^^^^^^^
|
help: change this to
|
-LL ~ fn foo_str(str: &Path) {
+LL ~ fn foo_str(str: &str) {
LL |
LL |
-LL ~ let _ = str.to_path_buf().pop();
-LL ~ let _ = str.to_path_buf().clone();
+LL ~ let e = str.to_owned().pop();
+LL ~ let f = str.to_owned().clone();
|
error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
@@ -231,6 +231,42 @@
LL | fn good(v1: &String, v2: &String) {
| ^^^^^^^ help: change this to: `&str`
+error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
+ --> tests/ui/ptr_arg.rs:363:20
+ |
+LL | fn foo_used(x: &Vec<i32>) {
+ | ^^^^^^^^^ help: change this to: `&[i32]`
+
+error: writing `&Vec` instead of `&[_]` involves a new object where a slice will do
+ --> tests/ui/ptr_arg.rs:377:26
+ |
+LL | fn foo_local_used(x: &Vec<i32>) {
+ | ^^^^^^^^^ help: change this to: `&[i32]`
+
+error: writing `&String` instead of `&str` involves a new object where a slice will do
+ --> tests/ui/ptr_arg.rs:386:33
+ |
+LL | fn foofoo(_x: &Vec<i32>, y: &String) {
+ | ^^^^^^^ help: change this to: `&str`
+
+error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
+ --> tests/ui/ptr_arg.rs:407:20
+ |
+LL | fn bar_used(x: &mut Vec<u32>) {
+ | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]`
+
+error: writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
+ --> tests/ui/ptr_arg.rs:421:26
+ |
+LL | fn bar_local_used(x: &mut Vec<u32>) {
+ | ^^^^^^^^^^^^^ help: change this to: `&mut [u32]`
+
+error: writing `&mut String` instead of `&mut str` involves a new object where a slice will do
+ --> tests/ui/ptr_arg.rs:430:37
+ |
+LL | fn barbar(_x: &mut Vec<u32>, y: &mut String) {
+ | ^^^^^^^^^^^ help: change this to: `&mut str`
+
error: eliding a lifetime that's named elsewhere is confusing
--> tests/ui/ptr_arg.rs:314:36
|
@@ -248,5 +284,5 @@
LL | fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &'a str {
| ++
-error: aborting due to 27 previous errors
+error: aborting due to 33 previous errors
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
index 2033f31..71fea614 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
@@ -219,3 +219,11 @@
//~^ ptr_as_ptr
}
}
+
+#[allow(clippy::transmute_null_to_fn)]
+fn issue15283() {
+ unsafe {
+ let _: fn() = std::mem::transmute(std::ptr::null::<u8>());
+ //~^ ptr_as_ptr
+ }
+}
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
index 224d09b..4d50759 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
@@ -219,3 +219,11 @@ fn full_core_path() -> *const u32 {
//~^ ptr_as_ptr
}
}
+
+#[allow(clippy::transmute_null_to_fn)]
+fn issue15283() {
+ unsafe {
+ let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
+ //~^ ptr_as_ptr
+ }
+}
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
index 66dae8e..adad159 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
@@ -201,5 +201,11 @@
LL | core::ptr::null() as _
| ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
-error: aborting due to 33 previous errors
+error: `as` casting between raw pointers without changing their constness
+ --> tests/ui/ptr_as_ptr.rs:226:43
+ |
+LL | let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u8>()`
+
+error: aborting due to 34 previous errors
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
index ee716ef..5c6da6d 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.fixed
@@ -1,5 +1,9 @@
+#![warn(clippy::range_minus_one, clippy::range_plus_one)]
#![allow(unused_parens)]
#![allow(clippy::iter_with_drain)]
+
+use std::ops::{Index, IndexMut, Range, RangeBounds, RangeInclusive};
+
fn f() -> usize {
42
}
@@ -20,8 +24,6 @@
};
}
-#[warn(clippy::range_plus_one)]
-#[warn(clippy::range_minus_one)]
fn main() {
for _ in 0..2 {}
for _ in 0..=2 {}
@@ -45,15 +47,13 @@
//~^ range_plus_one
for _ in 0..=(1 + f()) {}
+ // Those are not linted, as in the general case we cannot be sure that the exact type won't be
+ // important.
let _ = ..11 - 1;
- let _ = ..11;
- //~^ range_minus_one
- let _ = ..11;
- //~^ range_minus_one
- let _ = (1..=11);
- //~^ range_plus_one
- let _ = ((f() + 1)..=f());
- //~^ range_plus_one
+ let _ = ..=11 - 1;
+ let _ = ..=(11 - 1);
+ let _ = (1..11 + 1);
+ let _ = (f() + 1)..(f() + 1);
const ONE: usize = 1;
// integer consts are linted, too
@@ -65,4 +65,118 @@
macro_plus_one!(5);
macro_minus_one!(5);
+
+ // As an instance of `Iterator`
+ (1..=10).for_each(|_| {});
+ //~^ range_plus_one
+
+ // As an instance of `IntoIterator`
+ #[allow(clippy::useless_conversion)]
+ (1..=10).into_iter().for_each(|_| {});
+ //~^ range_plus_one
+
+ // As an instance of `RangeBounds`
+ {
+ let _ = (1..=10).start_bound();
+ //~^ range_plus_one
+ }
+
+ // As a `SliceIndex`
+ let a = [10, 20, 30];
+ let _ = &a[1..=1];
+ //~^ range_plus_one
+
+ // As method call argument
+ vec.drain(2..=3);
+ //~^ range_plus_one
+
+ // As function call argument
+ take_arg(10..=20);
+ //~^ range_plus_one
+
+ // As function call argument inside a block
+ take_arg({ 10..=20 });
+ //~^ range_plus_one
+
+ // Do not lint in case types are unified
+ take_arg(if true { 10..20 } else { 10..20 + 1 });
+
+ // Do not lint, as the same type is used for both parameters
+ take_args(10..20 + 1, 10..21);
+
+ // Do not lint, as the range type is also used indirectly in second parameter
+ take_arg_and_struct(10..20 + 1, S { t: 1..2 });
+
+ // As target of `IndexMut`
+ let mut a = [10, 20, 30];
+ a[0..=2][0] = 1;
+ //~^ range_plus_one
+}
+
+fn take_arg<T: Iterator<Item = u32>>(_: T) {}
+fn take_args<T: Iterator<Item = u32>>(_: T, _: T) {}
+
+struct S<T> {
+ t: T,
+}
+fn take_arg_and_struct<T: Iterator<Item = u32>>(_: T, _: S<T>) {}
+
+fn no_index_by_range_inclusive(a: usize) {
+ struct S;
+
+ impl Index<Range<usize>> for S {
+ type Output = [u32];
+ fn index(&self, _: Range<usize>) -> &Self::Output {
+ &[]
+ }
+ }
+
+ _ = &S[0..a + 1];
+}
+
+fn no_index_mut_with_switched_range(a: usize) {
+ struct S(u32);
+
+ impl Index<Range<usize>> for S {
+ type Output = u32;
+ fn index(&self, _: Range<usize>) -> &Self::Output {
+ &self.0
+ }
+ }
+
+ impl IndexMut<Range<usize>> for S {
+ fn index_mut(&mut self, _: Range<usize>) -> &mut Self::Output {
+ &mut self.0
+ }
+ }
+
+ impl Index<RangeInclusive<usize>> for S {
+ type Output = u32;
+ fn index(&self, _: RangeInclusive<usize>) -> &Self::Output {
+ &self.0
+ }
+ }
+
+ S(2)[0..a + 1] = 3;
+}
+
+fn issue9908() {
+ // Simplified test case
+ let _ = || 0..=1;
+
+ // Original test case
+ let full_length = 1024;
+ let range = {
+ // do some stuff, omit here
+ None
+ };
+
+ let range = range.map(|(s, t)| s..=t).unwrap_or(0..=(full_length - 1));
+
+ assert_eq!(range, 0..=1023);
+}
+
+fn issue9908_2(n: usize) -> usize {
+ (1..n).sum()
+ //~^ range_minus_one
}
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.rs b/src/tools/clippy/tests/ui/range_plus_minus_one.rs
index f2d5ae2..7172da6 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.rs
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.rs
@@ -1,5 +1,9 @@
+#![warn(clippy::range_minus_one, clippy::range_plus_one)]
#![allow(unused_parens)]
#![allow(clippy::iter_with_drain)]
+
+use std::ops::{Index, IndexMut, Range, RangeBounds, RangeInclusive};
+
fn f() -> usize {
42
}
@@ -20,8 +24,6 @@ macro_rules! macro_minus_one {
};
}
-#[warn(clippy::range_plus_one)]
-#[warn(clippy::range_minus_one)]
fn main() {
for _ in 0..2 {}
for _ in 0..=2 {}
@@ -45,15 +47,13 @@ fn main() {
//~^ range_plus_one
for _ in 0..=(1 + f()) {}
+ // Those are not linted, as in the general case we cannot be sure that the exact type won't be
+ // important.
let _ = ..11 - 1;
let _ = ..=11 - 1;
- //~^ range_minus_one
let _ = ..=(11 - 1);
- //~^ range_minus_one
let _ = (1..11 + 1);
- //~^ range_plus_one
let _ = (f() + 1)..(f() + 1);
- //~^ range_plus_one
const ONE: usize = 1;
// integer consts are linted, too
@@ -65,4 +65,118 @@ fn main() {
macro_plus_one!(5);
macro_minus_one!(5);
+
+ // As an instance of `Iterator`
+ (1..10 + 1).for_each(|_| {});
+ //~^ range_plus_one
+
+ // As an instance of `IntoIterator`
+ #[allow(clippy::useless_conversion)]
+ (1..10 + 1).into_iter().for_each(|_| {});
+ //~^ range_plus_one
+
+ // As an instance of `RangeBounds`
+ {
+ let _ = (1..10 + 1).start_bound();
+ //~^ range_plus_one
+ }
+
+ // As a `SliceIndex`
+ let a = [10, 20, 30];
+ let _ = &a[1..1 + 1];
+ //~^ range_plus_one
+
+ // As method call argument
+ vec.drain(2..3 + 1);
+ //~^ range_plus_one
+
+ // As function call argument
+ take_arg(10..20 + 1);
+ //~^ range_plus_one
+
+ // As function call argument inside a block
+ take_arg({ 10..20 + 1 });
+ //~^ range_plus_one
+
+ // Do not lint in case types are unified
+ take_arg(if true { 10..20 } else { 10..20 + 1 });
+
+ // Do not lint, as the same type is used for both parameters
+ take_args(10..20 + 1, 10..21);
+
+ // Do not lint, as the range type is also used indirectly in second parameter
+ take_arg_and_struct(10..20 + 1, S { t: 1..2 });
+
+ // As target of `IndexMut`
+ let mut a = [10, 20, 30];
+ a[0..2 + 1][0] = 1;
+ //~^ range_plus_one
+}
+
+fn take_arg<T: Iterator<Item = u32>>(_: T) {}
+fn take_args<T: Iterator<Item = u32>>(_: T, _: T) {}
+
+struct S<T> {
+ t: T,
+}
+fn take_arg_and_struct<T: Iterator<Item = u32>>(_: T, _: S<T>) {}
+
+fn no_index_by_range_inclusive(a: usize) {
+ struct S;
+
+ impl Index<Range<usize>> for S {
+ type Output = [u32];
+ fn index(&self, _: Range<usize>) -> &Self::Output {
+ &[]
+ }
+ }
+
+ _ = &S[0..a + 1];
+}
+
+fn no_index_mut_with_switched_range(a: usize) {
+ struct S(u32);
+
+ impl Index<Range<usize>> for S {
+ type Output = u32;
+ fn index(&self, _: Range<usize>) -> &Self::Output {
+ &self.0
+ }
+ }
+
+ impl IndexMut<Range<usize>> for S {
+ fn index_mut(&mut self, _: Range<usize>) -> &mut Self::Output {
+ &mut self.0
+ }
+ }
+
+ impl Index<RangeInclusive<usize>> for S {
+ type Output = u32;
+ fn index(&self, _: RangeInclusive<usize>) -> &Self::Output {
+ &self.0
+ }
+ }
+
+ S(2)[0..a + 1] = 3;
+}
+
+fn issue9908() {
+ // Simplified test case
+ let _ = || 0..=1;
+
+ // Original test case
+ let full_length = 1024;
+ let range = {
+ // do some stuff, omit here
+ None
+ };
+
+ let range = range.map(|(s, t)| s..=t).unwrap_or(0..=(full_length - 1));
+
+ assert_eq!(range, 0..=1023);
+}
+
+fn issue9908_2(n: usize) -> usize {
+ (1..=n - 1).sum()
+ //~^ range_minus_one
}
diff --git a/src/tools/clippy/tests/ui/range_plus_minus_one.stderr b/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
index 9b23a8b..a419d93 100644
--- a/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
+++ b/src/tools/clippy/tests/ui/range_plus_minus_one.stderr
@@ -1,5 +1,5 @@
error: an inclusive range would be more readable
- --> tests/ui/range_plus_minus_one.rs:29:14
+ --> tests/ui/range_plus_minus_one.rs:31:14
|
LL | for _ in 0..3 + 1 {}
| ^^^^^^^^ help: use: `0..=3`
@@ -8,55 +8,85 @@
= help: to override `-D warnings` add `#[allow(clippy::range_plus_one)]`
error: an inclusive range would be more readable
- --> tests/ui/range_plus_minus_one.rs:33:14
+ --> tests/ui/range_plus_minus_one.rs:35:14
|
LL | for _ in 0..1 + 5 {}
| ^^^^^^^^ help: use: `0..=5`
error: an inclusive range would be more readable
- --> tests/ui/range_plus_minus_one.rs:37:14
+ --> tests/ui/range_plus_minus_one.rs:39:14
|
LL | for _ in 1..1 + 1 {}
| ^^^^^^^^ help: use: `1..=1`
error: an inclusive range would be more readable
- --> tests/ui/range_plus_minus_one.rs:44:14
+ --> tests/ui/range_plus_minus_one.rs:46:14
|
LL | for _ in 0..(1 + f()) {}
| ^^^^^^^^^^^^ help: use: `0..=f()`
-error: an exclusive range would be more readable
- --> tests/ui/range_plus_minus_one.rs:49:13
- |
-LL | let _ = ..=11 - 1;
- | ^^^^^^^^^ help: use: `..11`
- |
- = note: `-D clippy::range-minus-one` implied by `-D warnings`
- = help: to override `-D warnings` add `#[allow(clippy::range_minus_one)]`
-
-error: an exclusive range would be more readable
- --> tests/ui/range_plus_minus_one.rs:51:13
- |
-LL | let _ = ..=(11 - 1);
- | ^^^^^^^^^^^ help: use: `..11`
-
-error: an inclusive range would be more readable
- --> tests/ui/range_plus_minus_one.rs:53:13
- |
-LL | let _ = (1..11 + 1);
- | ^^^^^^^^^^^ help: use: `(1..=11)`
-
-error: an inclusive range would be more readable
- --> tests/ui/range_plus_minus_one.rs:55:13
- |
-LL | let _ = (f() + 1)..(f() + 1);
- | ^^^^^^^^^^^^^^^^^^^^ help: use: `((f() + 1)..=f())`
-
error: an inclusive range would be more readable
--> tests/ui/range_plus_minus_one.rs:60:14
|
LL | for _ in 1..ONE + ONE {}
| ^^^^^^^^^^^^ help: use: `1..=ONE`
-error: aborting due to 9 previous errors
+error: an inclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:70:5
+ |
+LL | (1..10 + 1).for_each(|_| {});
+ | ^^^^^^^^^^^ help: use: `(1..=10)`
+
+error: an inclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:75:5
+ |
+LL | (1..10 + 1).into_iter().for_each(|_| {});
+ | ^^^^^^^^^^^ help: use: `(1..=10)`
+
+error: an inclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:80:17
+ |
+LL | let _ = (1..10 + 1).start_bound();
+ | ^^^^^^^^^^^ help: use: `(1..=10)`
+
+error: an inclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:86:16
+ |
+LL | let _ = &a[1..1 + 1];
+ | ^^^^^^^^ help: use: `1..=1`
+
+error: an inclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:90:15
+ |
+LL | vec.drain(2..3 + 1);
+ | ^^^^^^^^ help: use: `2..=3`
+
+error: an inclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:94:14
+ |
+LL | take_arg(10..20 + 1);
+ | ^^^^^^^^^^ help: use: `10..=20`
+
+error: an inclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:98:16
+ |
+LL | take_arg({ 10..20 + 1 });
+ | ^^^^^^^^^^ help: use: `10..=20`
+
+error: an inclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:112:7
+ |
+LL | a[0..2 + 1][0] = 1;
+ | ^^^^^^^^ help: use: `0..=2`
+
+error: an exclusive range would be more readable
+ --> tests/ui/range_plus_minus_one.rs:180:5
+ |
+LL | (1..=n - 1).sum()
+ | ^^^^^^^^^^^ help: use: `(1..n)`
+ |
+ = note: `-D clippy::range-minus-one` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::range_minus_one)]`
+
+error: aborting due to 14 previous errors
diff --git a/src/tools/clippy/tests/ui/single_match_else_deref_patterns.fixed b/src/tools/clippy/tests/ui/single_match_else_deref_patterns.fixed
new file mode 100644
index 0000000..7a9f8063
--- /dev/null
+++ b/src/tools/clippy/tests/ui/single_match_else_deref_patterns.fixed
@@ -0,0 +1,53 @@
+#![feature(deref_patterns)]
+#![allow(
+ incomplete_features,
+ clippy::eq_op,
+ clippy::op_ref,
+ clippy::deref_addrof,
+ clippy::borrow_deref_ref,
+ clippy::needless_if
+)]
+#![deny(clippy::single_match_else)]
+
+fn string() {
+ if *"" == *"" {}
+
+ if *&*&*&*"" == *"" {}
+
+ if ***&&"" == *"" {}
+
+ if *&*&*"" == *"" {}
+
+ if **&&*"" == *"" {}
+}
+
+fn int() {
+ if &&&1 == &&&2 { unreachable!() } else {
+ // ok
+ }
+ //~^^^^^^ single_match_else
+ if &&1 == &&2 { unreachable!() } else {
+ // ok
+ }
+ //~^^^^^^ single_match_else
+ if &&1 == &&2 { unreachable!() } else {
+ // ok
+ }
+ //~^^^^^^ single_match_else
+ if &1 == &2 { unreachable!() } else {
+ // ok
+ }
+ //~^^^^^^ single_match_else
+ if &1 == &2 { unreachable!() } else {
+ // ok
+ }
+ //~^^^^^^ single_match_else
+ if 1 == 2 { unreachable!() } else {
+ // ok
+ }
+ //~^^^^^^ single_match_else
+ if 1 == 2 { unreachable!() } else {
+ // ok
+ }
+ //~^^^^^^ single_match_else
+}
diff --git a/src/tools/clippy/tests/ui/single_match_else_deref_patterns.rs b/src/tools/clippy/tests/ui/single_match_else_deref_patterns.rs
new file mode 100644
index 0000000..ef19c7c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/single_match_else_deref_patterns.rs
@@ -0,0 +1,94 @@
+#![feature(deref_patterns)]
+#![allow(
+ incomplete_features,
+ clippy::eq_op,
+ clippy::op_ref,
+ clippy::deref_addrof,
+ clippy::borrow_deref_ref,
+ clippy::needless_if
+)]
+#![deny(clippy::single_match_else)]
+
+fn string() {
+ match *"" {
+ //~^ single_match
+ "" => {},
+ _ => {},
+ }
+
+ match *&*&*&*"" {
+ //~^ single_match
+ "" => {},
+ _ => {},
+ }
+
+ match ***&&"" {
+ //~^ single_match
+ "" => {},
+ _ => {},
+ }
+
+ match *&*&*"" {
+ //~^ single_match
+ "" => {},
+ _ => {},
+ }
+
+ match **&&*"" {
+ //~^ single_match
+ "" => {},
+ _ => {},
+ }
+}
+
+fn int() {
+ match &&&1 {
+ &&&2 => unreachable!(),
+ _ => {
+ // ok
+ },
+ }
+ //~^^^^^^ single_match_else
+ match &&&1 {
+ &&2 => unreachable!(),
+ _ => {
+ // ok
+ },
+ }
+ //~^^^^^^ single_match_else
+ match &&1 {
+ &&2 => unreachable!(),
+ _ => {
+ // ok
+ },
+ }
+ //~^^^^^^ single_match_else
+ match &&&1 {
+ &2 => unreachable!(),
+ _ => {
+ // ok
+ },
+ }
+ //~^^^^^^ single_match_else
+ match &&1 {
+ &2 => unreachable!(),
+ _ => {
+ // ok
+ },
+ }
+ //~^^^^^^ single_match_else
+ match &&&1 {
+ 2 => unreachable!(),
+ _ => {
+ // ok
+ },
+ }
+ //~^^^^^^ single_match_else
+ match &&1 {
+ 2 => unreachable!(),
+ _ => {
+ // ok
+ },
+ }
+ //~^^^^^^ single_match_else
+}
diff --git a/src/tools/clippy/tests/ui/single_match_else_deref_patterns.stderr b/src/tools/clippy/tests/ui/single_match_else_deref_patterns.stderr
new file mode 100644
index 0000000..a47df55
--- /dev/null
+++ b/src/tools/clippy/tests/ui/single_match_else_deref_patterns.stderr
@@ -0,0 +1,188 @@
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:13:5
+ |
+LL | / match *"" {
+LL | |
+LL | | "" => {},
+LL | | _ => {},
+LL | | }
+ | |_____^ help: try: `if *"" == *"" {}`
+ |
+ = note: you might want to preserve the comments from inside the `match`
+ = note: `-D clippy::single-match` implied by `-D warnings`
+ = help: to override `-D warnings` add `#[allow(clippy::single_match)]`
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:19:5
+ |
+LL | / match *&*&*&*"" {
+LL | |
+LL | | "" => {},
+LL | | _ => {},
+LL | | }
+ | |_____^ help: try: `if *&*&*&*"" == *"" {}`
+ |
+ = note: you might want to preserve the comments from inside the `match`
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:25:5
+ |
+LL | / match ***&&"" {
+LL | |
+LL | | "" => {},
+LL | | _ => {},
+LL | | }
+ | |_____^ help: try: `if ***&&"" == *"" {}`
+ |
+ = note: you might want to preserve the comments from inside the `match`
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:31:5
+ |
+LL | / match *&*&*"" {
+LL | |
+LL | | "" => {},
+LL | | _ => {},
+LL | | }
+ | |_____^ help: try: `if *&*&*"" == *"" {}`
+ |
+ = note: you might want to preserve the comments from inside the `match`
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:37:5
+ |
+LL | / match **&&*"" {
+LL | |
+LL | | "" => {},
+LL | | _ => {},
+LL | | }
+ | |_____^ help: try: `if **&&*"" == *"" {}`
+ |
+ = note: you might want to preserve the comments from inside the `match`
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:45:5
+ |
+LL | / match &&&1 {
+LL | | &&&2 => unreachable!(),
+LL | | _ => {
+... |
+LL | | }
+ | |_____^
+ |
+note: the lint level is defined here
+ --> tests/ui/single_match_else_deref_patterns.rs:10:9
+ |
+LL | #![deny(clippy::single_match_else)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: try
+ |
+LL ~ if &&&1 == &&&2 { unreachable!() } else {
+LL + // ok
+LL + }
+ |
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:52:5
+ |
+LL | / match &&&1 {
+LL | | &&2 => unreachable!(),
+LL | | _ => {
+... |
+LL | | }
+ | |_____^
+ |
+help: try
+ |
+LL ~ if &&1 == &&2 { unreachable!() } else {
+LL + // ok
+LL + }
+ |
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:59:5
+ |
+LL | / match &&1 {
+LL | | &&2 => unreachable!(),
+LL | | _ => {
+... |
+LL | | }
+ | |_____^
+ |
+help: try
+ |
+LL ~ if &&1 == &&2 { unreachable!() } else {
+LL + // ok
+LL + }
+ |
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:66:5
+ |
+LL | / match &&&1 {
+LL | | &2 => unreachable!(),
+LL | | _ => {
+... |
+LL | | }
+ | |_____^
+ |
+help: try
+ |
+LL ~ if &1 == &2 { unreachable!() } else {
+LL + // ok
+LL + }
+ |
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:73:5
+ |
+LL | / match &&1 {
+LL | | &2 => unreachable!(),
+LL | | _ => {
+... |
+LL | | }
+ | |_____^
+ |
+help: try
+ |
+LL ~ if &1 == &2 { unreachable!() } else {
+LL + // ok
+LL + }
+ |
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:80:5
+ |
+LL | / match &&&1 {
+LL | | 2 => unreachable!(),
+LL | | _ => {
+... |
+LL | | }
+ | |_____^
+ |
+help: try
+ |
+LL ~ if 1 == 2 { unreachable!() } else {
+LL + // ok
+LL + }
+ |
+
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+ --> tests/ui/single_match_else_deref_patterns.rs:87:5
+ |
+LL | / match &&1 {
+LL | | 2 => unreachable!(),
+LL | | _ => {
+... |
+LL | | }
+ | |_____^
+ |
+help: try
+ |
+LL ~ if 1 == 2 { unreachable!() } else {
+LL + // ok
+LL + }
+ |
+
+error: aborting due to 12 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
index 14371bc..d0022f3 100644
--- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
+++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
@@ -82,3 +82,32 @@ pub fn unsafe_block(&self) {
}
fn main() {}
+
+mod issue15120 {
+ macro_rules! uns {
+ ($e:expr) => {
+ unsafe { $e }
+ };
+ }
+
+ #[derive(serde::Deserialize)]
+ struct Foo;
+
+ impl Foo {
+ fn foo(&self) {
+ // Do not lint if `unsafe` comes from the `core::pin::pin!()` macro
+ std::pin::pin!(());
+ }
+ }
+
+ //~v unsafe_derive_deserialize
+ #[derive(serde::Deserialize)]
+ struct Bar;
+
+ impl Bar {
+ fn bar(&self) {
+ // Lint if `unsafe` comes from the another macro
+ _ = uns!(42);
+ }
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
index f2d4429..4b5dd6e 100644
--- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
+++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr
@@ -36,5 +36,14 @@
= help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: aborting due to 4 previous errors
+error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
+ --> tests/ui/unsafe_derive_deserialize.rs:104:14
+ |
+LL | #[derive(serde::Deserialize)]
+ | ^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html
+ = note: this error originates in the derive macro `serde::Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
diff --git a/src/tools/clippy/tests/ui/unused_async.rs b/src/tools/clippy/tests/ui/unused_async.rs
index 4334592..7a0be82 100644
--- a/src/tools/clippy/tests/ui/unused_async.rs
+++ b/src/tools/clippy/tests/ui/unused_async.rs
@@ -127,3 +127,13 @@ trait Action {
async fn cancel(self: Arc<Self>) {}
}
}
+
+mod issue15305 {
+ async fn todo_task() -> Result<(), String> {
+ todo!("Implement task");
+ }
+
+ async fn unimplemented_task() -> Result<(), String> {
+ unimplemented!("Implement task");
+ }
+}
diff --git a/src/tools/clippy/tests/ui/unused_trait_names.fixed b/src/tools/clippy/tests/ui/unused_trait_names.fixed
index 17e32dd..6abbed0 100644
--- a/src/tools/clippy/tests/ui/unused_trait_names.fixed
+++ b/src/tools/clippy/tests/ui/unused_trait_names.fixed
@@ -200,11 +200,11 @@
MyStruct.do_things();
}
+// Linting inside macro expansion is no longer supported
mod lint_inside_macro_expansion_bad {
macro_rules! foo {
() => {
- use std::any::Any as _;
- //~^ unused_trait_names
+ use std::any::Any;
fn bar() {
"bar".type_id();
}
diff --git a/src/tools/clippy/tests/ui/unused_trait_names.rs b/src/tools/clippy/tests/ui/unused_trait_names.rs
index 3cf8597..4a06f06 100644
--- a/src/tools/clippy/tests/ui/unused_trait_names.rs
+++ b/src/tools/clippy/tests/ui/unused_trait_names.rs
@@ -200,11 +200,11 @@ fn msrv_1_33() {
MyStruct.do_things();
}
+// Linting inside macro expansion is no longer supported
mod lint_inside_macro_expansion_bad {
macro_rules! foo {
() => {
use std::any::Any;
- //~^ unused_trait_names
fn bar() {
"bar".type_id();
}
diff --git a/src/tools/clippy/tests/ui/unused_trait_names.stderr b/src/tools/clippy/tests/ui/unused_trait_names.stderr
index 3183289..28067e1 100644
--- a/src/tools/clippy/tests/ui/unused_trait_names.stderr
+++ b/src/tools/clippy/tests/ui/unused_trait_names.stderr
@@ -58,16 +58,5 @@
LL | use simple_trait::{MyStruct, MyTrait};
| ^^^^^^^ help: use: `MyTrait as _`
-error: importing trait that is only used anonymously
- --> tests/ui/unused_trait_names.rs:206:27
- |
-LL | use std::any::Any;
- | ^^^ help: use: `Any as _`
-...
-LL | foo!();
- | ------ in this macro invocation
- |
- = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 10 previous errors
+error: aborting due to 9 previous errors
diff --git a/src/tools/clippy/tests/ui/used_underscore_items.rs b/src/tools/clippy/tests/ui/used_underscore_items.rs
index 7e8289f..aecdd32 100644
--- a/src/tools/clippy/tests/ui/used_underscore_items.rs
+++ b/src/tools/clippy/tests/ui/used_underscore_items.rs
@@ -62,13 +62,13 @@ fn main() {
//~^ used_underscore_items
}
-// should not lint exteranl crate.
+// should not lint external crate.
// user cannot control how others name their items
fn external_item_call() {
let foo_struct3 = external_item::_ExternalStruct {};
foo_struct3._foo();
- external_item::_exernal_foo();
+ external_item::_external_foo();
}
// should not lint foreign functions.
diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed
index 930bc1e..be4fb55 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.fixed
+++ b/src/tools/clippy/tests/ui/useless_attribute.fixed
@@ -146,3 +146,15 @@
#[allow(rustc::non_glob_import_of_type_ir_inherent)]
use some_module::SomeType;
}
+
+// Regression test for https://github.com/rust-lang/rust-clippy/issues/15316
+pub mod redundant_imports_issue {
+ macro_rules! empty {
+ () => {};
+ }
+
+ #[expect(redundant_imports)]
+ pub(crate) use empty;
+
+ empty!();
+}
diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs
index 50fafd4..5a1bcf9 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.rs
+++ b/src/tools/clippy/tests/ui/useless_attribute.rs
@@ -146,3 +146,15 @@ pub mod some_module {
#[allow(rustc::non_glob_import_of_type_ir_inherent)]
use some_module::SomeType;
}
+
+// Regression test for https://github.com/rust-lang/rust-clippy/issues/15316
+pub mod redundant_imports_issue {
+ macro_rules! empty {
+ () => {};
+ }
+
+ #[expect(redundant_imports)]
+ pub(crate) use empty;
+
+ empty!();
+}
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index 805baf2..a62b626 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -54,6 +54,7 @@
users_on_vacation = [
"matthiaskrgr",
"Manishearth",
+ "samueltardieu",
]
[assign.owners]
diff --git a/src/tools/clippy/util/gh-pages/index_template.html b/src/tools/clippy/util/gh-pages/index_template.html
index 6f380ec..5d65ea5 100644
--- a/src/tools/clippy/util/gh-pages/index_template.html
+++ b/src/tools/clippy/util/gh-pages/index_template.html
@@ -49,9 +49,7 @@
<script src="theme.js"></script> {# #}
<div class="container"> {# #}
- <div class="page-header"> {# #}
- <h1>Clippy Lints <span id="lint-count" class="badge"></span></h1> {# #}
- </div> {# #}
+ <h1 class="page-header">Clippy Lints <span id="lint-count" class="badge"></span></h1> {# #}
<noscript> {# #}
<div class="alert alert-danger" role="alert"> {# #}
@@ -59,143 +57,141 @@
</div> {# #}
</noscript> {# #}
- <div> {# #}
- <div class="panel panel-default" id="menu-filters"> {# #}
- <div class="panel-body row"> {# #}
- <div id="upper-filters" class="col-12 col-md-5"> {# #}
- <div class="btn-group" id="lint-levels" tabindex="-1"> {# #}
- <button type="button" class="btn btn-default dropdown-toggle"> {# #}
- Lint levels <span class="badge">4</span> <span class="caret"></span> {# #}
- </button> {# #}
- <ul class="dropdown-menu" id="lint-levels-selector"> {# #}
- <li class="checkbox"> {# #}
- <button onclick="toggleElements('levels_filter', true)">All</button> {# #}
- </li> {# #}
- <li class="checkbox"> {# #}
- <button onclick="toggleElements('levels_filter', false)">None</button> {# #}
- </li> {# #}
- <li role="separator" class="divider"></li> {# #}
- </ul> {# #}
- </div> {# #}
- <div class="btn-group" id="lint-groups" tabindex="-1"> {# #}
- <button type="button" class="btn btn-default dropdown-toggle"> {# #}
- Lint groups <span class="badge">9</span> <span class="caret"></span> {# #}
- </button> {# #}
- <ul class="dropdown-menu" id="lint-groups-selector"> {# #}
- <li class="checkbox"> {# #}
- <button onclick="toggleElements('groups_filter', true)">All</button> {# #}
- </li> {# #}
- <li class="checkbox"> {# #}
- <button onclick="resetGroupsToDefault()">Default</button> {# #}
- </li> {# #}
- <li class="checkbox"> {# #}
- <button onclick="toggleElements('groups_filter', false)">None</button> {# #}
- </li> {# #}
- <li role="separator" class="divider"></li> {# #}
- </ul> {# #}
- </div> {# #}
- <div class="btn-group" id="version-filter" tabindex="-1"> {# #}
- <button type="button" class="btn btn-default dropdown-toggle"> {# #}
- Version {#+ #}
- <span id="version-filter-count" class="badge">0</span> {#+ #}
- <span class="caret"></span> {# #}
- </button> {# #}
- <ul id="version-filter-selector" class="dropdown-menu"> {# #}
- <li class="checkbox"> {# #}
- <button onclick="clearVersionFilters()">Clear filters</button> {# #}
- </li> {# #}
- <li role="separator" class="divider"></li> {# #}
- </ul> {# #}
- </div> {# #}
- <div class="btn-group" id="lint-applicabilities" tabindex="-1"> {# #}
- <button type="button" class="btn btn-default dropdown-toggle"> {# #}
- Applicability {#+ #}
- <span class="badge">4</span> {#+ #}
- <span class="caret"></span> {# #}
- </button> {# #}
- <ul class="dropdown-menu" id="lint-applicabilities-selector"> {# #}
- <li class="checkbox"> {# #}
- <button onclick="toggleElements('applicabilities_filter', true)">All</button> {# #}
- </li> {# #}
- <li class="checkbox"> {# #}
- <button onclick="toggleElements('applicabilities_filter', false)">None</button> {# #}
- </li> {# #}
- <li role="separator" class="divider"></li> {# #}
- </ul> {# #}
- </div> {# #}
- </div> {# #}
- <div class="col-12 col-md-5 search-control"> {# #}
- <div class="input-group"> {# #}
- <label class="input-group-addon" id="filter-label" for="search-input">Filter:</label> {# #}
- <input type="text" class="form-control filter-input" placeholder="Keywords or search string (`S` or `/` to focus)" id="search-input" /> {# #}
- <span class="input-group-btn"> {# #}
- <button class="filter-clear btn" type="button" onclick="searchState.clearInput(event)"> {# #}
- Clear {# #}
- </button> {# #}
- </span> {# #}
- </div> {# #}
- </div> {# #}
- <div class="col-12 col-md-2 btn-group expansion-group"> {# #}
- <button title="Collapse All" class="btn btn-default expansion-control" type="button" id="collapse-all"> {# #}
- <span class="glyphicon glyphicon-collapse-up"></span> {# #}
+ <div id="menu-filters"> {# #}
+ <div class="panel-body row"> {# #}
+ <div id="upper-filters" class="col-12 col-md-5"> {# #}
+ <div class="btn-group" id="lint-levels" tabindex="-1"> {# #}
+ <button type="button" class="btn btn-default dropdown-toggle"> {# #}
+ Lint levels <span class="badge">4</span> <span class="caret"></span> {# #}
</button> {# #}
- <button title="Expand All" class="btn btn-default expansion-control" type="button" id="expand-all"> {# #}
- <span class="glyphicon glyphicon-collapse-down"></span> {# #}
+ <ul class="dropdown-menu" id="lint-levels-selector"> {# #}
+ <li class="checkbox"> {# #}
+ <button onclick="toggleElements('levels_filter', true)">All</button> {# #}
+ </li> {# #}
+ <li class="checkbox"> {# #}
+ <button onclick="toggleElements('levels_filter', false)">None</button> {# #}
+ </li> {# #}
+ <li role="separator" class="divider"></li> {# #}
+ </ul> {# #}
+ </div> {# #}
+ <div class="btn-group" id="lint-groups" tabindex="-1"> {# #}
+ <button type="button" class="btn btn-default dropdown-toggle"> {# #}
+ Lint groups <span class="badge">9</span> <span class="caret"></span> {# #}
</button> {# #}
+ <ul class="dropdown-menu" id="lint-groups-selector"> {# #}
+ <li class="checkbox"> {# #}
+ <button onclick="toggleElements('groups_filter', true)">All</button> {# #}
+ </li> {# #}
+ <li class="checkbox"> {# #}
+ <button onclick="resetGroupsToDefault()">Default</button> {# #}
+ </li> {# #}
+ <li class="checkbox"> {# #}
+ <button onclick="toggleElements('groups_filter', false)">None</button> {# #}
+ </li> {# #}
+ <li role="separator" class="divider"></li> {# #}
+ </ul> {# #}
+ </div> {# #}
+ <div class="btn-group" id="version-filter" tabindex="-1"> {# #}
+ <button type="button" class="btn btn-default dropdown-toggle"> {# #}
+ Version {#+ #}
+ <span id="version-filter-count" class="badge">0</span> {#+ #}
+ <span class="caret"></span> {# #}
+ </button> {# #}
+ <ul id="version-filter-selector" class="dropdown-menu"> {# #}
+ <li class="checkbox"> {# #}
+ <button onclick="clearVersionFilters()">Clear filters</button> {# #}
+ </li> {# #}
+ <li role="separator" class="divider"></li> {# #}
+ </ul> {# #}
+ </div> {# #}
+ <div class="btn-group" id="lint-applicabilities" tabindex="-1"> {# #}
+ <button type="button" class="btn btn-default dropdown-toggle"> {# #}
+ Applicability {#+ #}
+ <span class="badge">4</span> {#+ #}
+ <span class="caret"></span> {# #}
+ </button> {# #}
+ <ul class="dropdown-menu" id="lint-applicabilities-selector"> {# #}
+ <li class="checkbox"> {# #}
+ <button onclick="toggleElements('applicabilities_filter', true)">All</button> {# #}
+ </li> {# #}
+ <li class="checkbox"> {# #}
+ <button onclick="toggleElements('applicabilities_filter', false)">None</button> {# #}
+ </li> {# #}
+ <li role="separator" class="divider"></li> {# #}
+ </ul> {# #}
</div> {# #}
</div> {# #}
- </div>
- {% for lint in lints %}
- <article class="panel panel-default" id="{{lint.id}}"> {# #}
- <input id="label-{{lint.id}}" type="checkbox"> {# #}
- <label for="label-{{lint.id}}"> {# #}
- <h2 class="lint-title"> {# #}
- <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
- {{lint.id +}}
- <a href="#{{lint.id}}" class="anchor label label-default">¶</a> {#+ #}
- <a href="" class="copy-to-clipboard anchor label label-default"> {# #}
- 📋 {# #}
- </a> {# #}
- </div> {# #}
-
- <span class="label label-lint-group label-default label-group-{{lint.group}}">{{lint.group}}</span> {#+ #}
-
- <span class="label label-lint-level label-lint-level-{{lint.level}}">{{lint.level}}</span> {#+ #}
-
- <span class="label label-doc-folding"></span> {# #}
- </h2> {# #}
- </label> {# #}
-
- <div class="list-group lint-docs"> {# #}
- <div class="list-group-item lint-doc-md">{{Self::markdown(lint.docs)}}</div> {# #}
- <div class="lint-additional-info-container">
- {# Applicability #}
- <div> {# #}
- Applicability: {#+ #}
- <span class="label label-default label-applicability">{{ lint.applicability_str() }}</span> {# #}
- <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.Applicability.html#variants">(?)</a> {# #}
- </div>
- {# Clippy version #}
- <div> {# #}
- {% if lint.group == "deprecated" %}Deprecated{% else %} Added{% endif +%} in: {#+ #}
- <span class="label label-default label-version">{{lint.version}}</span> {# #}
- </div>
- {# Open related issues #}
- <div> {# #}
- <a href="https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+{{lint.id}}">Related Issues</a> {# #}
- </div>
-
- {# Jump to source #}
- {% if let Some(id_location) = lint.id_location %}
- <div> {# #}
- <a href="https://github.com/rust-lang/rust-clippy/blob/master/{{id_location}}">View Source</a> {# #}
- </div>
- {% endif %}
- </div> {# #}
+ <div class="col-12 col-md-5 search-control"> {# #}
+ <div class="input-group"> {# #}
+ <label class="input-group-addon" id="filter-label" for="search-input">Filter:</label> {# #}
+ <input type="text" class="form-control filter-input" placeholder="Keywords or search string (`S` or `/` to focus)" id="search-input" /> {# #}
+ <span class="input-group-btn"> {# #}
+ <button class="filter-clear btn" type="button" onclick="searchState.clearInput(event)"> {# #}
+ Clear {# #}
+ </button> {# #}
+ </span> {# #}
</div> {# #}
- </article>
- {% endfor %}
- </div> {# #}
+ </div> {# #}
+ <div class="col-12 col-md-2 btn-group expansion-group"> {# #}
+ <button title="Collapse All" class="btn btn-default expansion-control" type="button" id="collapse-all"> {# #}
+ <span class="glyphicon glyphicon-collapse-up"></span> {# #}
+ </button> {# #}
+ <button title="Expand All" class="btn btn-default expansion-control" type="button" id="expand-all"> {# #}
+ <span class="glyphicon glyphicon-collapse-down"></span> {# #}
+ </button> {# #}
+ </div> {# #}
+ </div> {# #}
+ </div>
+ {% for lint in lints %}
+ <article id="{{lint.id}}"> {# #}
+ <input id="label-{{lint.id}}" type="checkbox"> {# #}
+ <label for="label-{{lint.id}}"> {# #}
+ <h2 class="lint-title"> {# #}
+ <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
+ {{lint.id ~}}
+ <a href="#{{lint.id}}" class="anchor label label-default">¶</a> {#+ #}
+ <a href="" class="copy-to-clipboard anchor label label-default"> {# #}
+ 📋 {# #}
+ </a> {# #}
+ </div> {# #}
+
+ <span class="label label-default lint-group group-{{lint.group}}">{{lint.group}}</span> {#+ #}
+
+ <span class="label lint-level level-{{lint.level}}">{{lint.level}}</span> {#+ #}
+
+ <span class="label doc-folding"></span> {# #}
+ </h2> {# #}
+ </label> {# #}
+
+ <div class="lint-docs"> {# #}
+ <div class="lint-doc-md">{{Self::markdown(lint.docs)}}</div> {# #}
+ <div class="lint-additional-info">
+ {# Applicability #}
+ <div> {# #}
+ Applicability: {#+ #}
+ <span class="label label-default applicability">{{ lint.applicability_str() }}</span> {# #}
+ <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.Applicability.html#variants">(?)</a> {# #}
+ </div>
+ {# Clippy version #}
+ <div> {# #}
+ {% if lint.group == "deprecated" %}Deprecated{% else %} Added{% endif +%} in: {#+ #}
+ <span class="label label-default label-version">{{lint.version}}</span> {# #}
+ </div>
+ {# Open related issues #}
+ <div> {# #}
+ <a href="https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+{{lint.id}}">Related Issues</a> {# #}
+ </div>
+
+ {# Jump to source #}
+ {% if let Some(id_location) = lint.id_location %}
+ <div> {# #}
+ <a href="https://github.com/rust-lang/rust-clippy/blob/master/{{id_location}}">View Source</a> {# #}
+ </div>
+ {% endif %}
+ </div> {# #}
+ </div> {# #}
+ </article>
+ {% endfor %}
</div> {# #}
<a {#+ #}
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index ee13f1c..d320496 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -208,7 +208,6 @@
allow: true,
warn: true,
deny: true,
- none: true,
};
const APPLICABILITIES_FILTER_DEFAULT = {
Unspecified: true,
@@ -250,10 +249,10 @@
}
return {
elem: elem,
- group: elem.querySelector(".label-lint-group").innerText,
- level: elem.querySelector(".label-lint-level").innerText,
+ group: elem.querySelector(".lint-group").innerText,
+ level: elem.querySelector(".lint-level").innerText,
version: parseInt(version.split(".")[1]),
- applicability: elem.querySelector(".label-applicability").innerText,
+ applicability: elem.querySelector(".applicability").innerText,
filteredOut: false,
searchFilteredOut: false,
};
@@ -594,19 +593,19 @@
addListeners();
highlightLazily();
+function updateLintCount() {
+ const allLints = filters.getAllLints().filter(lint => lint.group != "deprecated");
+ const totalLints = allLints.length;
+
+ const countElement = document.getElementById("lint-count");
+ if (countElement) {
+ countElement.innerText = `Total number: ${totalLints}`;
+ }
+}
+
generateSettings();
generateSearch();
parseURLFilters();
scrollToLintByURL();
filters.filterLints();
updateLintCount();
-
-function updateLintCount() {
- const allLints = filters.getAllLints().filter(lint => lint.group != "deprecated");
- const totalLints = allLints.length;
-
- const countElement = document.getElementById("lint-count");
- if (countElement) {
- countElement.innerText = `Total number: ${totalLints}`;
- }
-}
diff --git a/src/tools/clippy/util/gh-pages/style.css b/src/tools/clippy/util/gh-pages/style.css
index 022ea87..66abf45 100644
--- a/src/tools/clippy/util/gh-pages/style.css
+++ b/src/tools/clippy/util/gh-pages/style.css
@@ -30,17 +30,25 @@
background-color: var(--theme-hover);
}
-div.panel div.panel-body button {
+.container > * {
+ margin-bottom: 20px;
+ border-radius: 4px;
+ background: var(--bg);
+ border: 1px solid var(--theme-popup-border);
+ box-shadow: 0 1px 1px rgba(0,0,0,.05);
+}
+
+div.panel-body button {
background: var(--searchbar-bg);
color: var(--searchbar-fg);
border-color: var(--theme-popup-border);
}
-div.panel div.panel-body button:hover {
+div.panel-body button:hover {
box-shadow: 0 0 3px var(--searchbar-shadow-color);
}
-div.panel div.panel-body button.open {
+div.panel-body button.open {
filter: brightness(90%);
}
@@ -48,8 +56,6 @@
background-color: #777;
}
-.panel-heading { cursor: pointer; }
-
.lint-title {
cursor: pointer;
margin-top: 0;
@@ -70,8 +76,8 @@
.panel-title-name { flex: 1; min-width: 400px;}
-.panel .panel-title-name .anchor { display: none; }
-.panel:hover .panel-title-name .anchor { display: inline;}
+.panel-title-name .anchor { display: none; }
+article:hover .panel-title-name .anchor { display: inline;}
.search-control {
margin-top: 15px;
@@ -111,40 +117,48 @@
padding-bottom: 0.3em;
}
-.label-lint-group {
- min-width: 8em;
-}
-.label-lint-level {
+.lint-level {
min-width: 4em;
}
-
-.label-lint-level-allow {
+.level-allow {
background-color: #5cb85c;
}
-.label-lint-level-warn {
+.level-warn {
background-color: #f0ad4e;
}
-.label-lint-level-deny {
+.level-deny {
background-color: #d9534f;
}
-.label-lint-level-none {
+.level-none {
background-color: #777777;
opacity: 0.5;
}
-.label-group-deprecated {
+.lint-group {
+ min-width: 8em;
+}
+.group-deprecated {
opacity: 0.5;
}
-.label-doc-folding {
+.doc-folding {
color: #000;
background-color: #fff;
border: 1px solid var(--theme-popup-border);
}
-.label-doc-folding:hover {
+.doc-folding:hover {
background-color: #e6e6e6;
}
+.lint-doc-md {
+ position: relative;
+ display: block;
+ padding: 10px 15px;
+ margin-bottom: -1px;
+ background: 0%;
+ border-bottom: 1px solid var(--theme-popup-border);
+ border-top: 1px solid var(--theme-popup-border);
+}
.lint-doc-md > h3 {
border-top: 1px solid var(--theme-popup-border);
padding: 10px 15px;
@@ -157,32 +171,32 @@
}
@media (max-width:749px) {
- .lint-additional-info-container {
+ .lint-additional-info {
display: flex;
flex-flow: column;
}
- .lint-additional-info-container > div + div {
+ .lint-additional-info > div + div {
border-top: 1px solid var(--theme-popup-border);
}
}
@media (min-width:750px) {
- .lint-additional-info-container {
+ .lint-additional-info {
display: flex;
flex-flow: row;
}
- .lint-additional-info-container > div + div {
+ .lint-additional-info > div + div {
border-left: 1px solid var(--theme-popup-border);
}
}
-.lint-additional-info-container > div {
+.lint-additional-info > div {
display: inline-flex;
min-width: 200px;
flex-grow: 1;
padding: 9px 5px 5px 15px;
}
-.label-applicability {
+.applicability {
background-color: #777777;
margin: auto 5px;
}
@@ -332,21 +346,12 @@
border: 1px solid var(--theme-popup-border);
}
.page-header {
- border-color: var(--theme-popup-border);
+ border: 0;
+ border-bottom: 1px solid var(--theme-popup-border);
+ padding-bottom: 19px;
+ border-radius: 0;
}
-.panel-default .panel-heading {
- background: var(--theme-hover);
- color: var(--fg);
- border: 1px solid var(--theme-popup-border);
-}
-.panel-default .panel-heading:hover {
- filter: brightness(90%);
-}
-.list-group-item {
- background: 0%;
- border: 1px solid var(--theme-popup-border);
-}
-.panel, pre, hr {
+pre, hr {
background: var(--bg);
border: 1px solid var(--theme-popup-border);
}
@@ -442,14 +447,15 @@
article > input[type="checkbox"] {
display: none;
}
-article > input[type="checkbox"] + label .label-doc-folding::before {
+article > input[type="checkbox"] + label .doc-folding::before {
content: "+";
}
-article > input[type="checkbox"]:checked + label .label-doc-folding::before {
+article > input[type="checkbox"]:checked + label .doc-folding::before {
content: "−";
}
.lint-docs {
display: none;
+ margin-bottom: 0;
}
article > input[type="checkbox"]:checked ~ .lint-docs {
display: block;
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
index 236f316..372a9df 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout/adt.rs
@@ -3,9 +3,9 @@
use std::{cmp, ops::Bound};
use hir_def::{
- AdtId, VariantId,
layout::{Integer, ReprOptions, TargetDataLayout},
signatures::{StructFlags, VariantFields},
+ AdtId, VariantId,
};
use intern::sym;
use rustc_index::IndexVec;
@@ -13,9 +13,9 @@
use triomphe::Arc;
use crate::{
- Substitution, TraitEnvironment,
db::HirDatabase,
- layout::{Layout, LayoutError, field_ty},
+ layout::{field_ty, Layout, LayoutError},
+ Substitution, TraitEnvironment,
};
use super::LayoutCx;
@@ -85,16 +85,6 @@ pub fn layout_of_adt_query(
let d = db.const_eval_discriminant(e.enum_variants(db).variants[id.0].0).ok()?;
Some((id, d))
}),
- // FIXME: The current code for niche-filling relies on variant indices
- // instead of actual discriminants, so enums with
- // explicit discriminants (RFC #2363) would misbehave and we should disable
- // niche optimization for them.
- // The code that do it in rustc:
- // repr.inhibit_enum_layout_opt() || def
- // .variants()
- // .iter_enumerated()
- // .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()))
- repr.inhibit_enum_layout_opt(),
!matches!(def, AdtId::EnumId(..))
&& variants
.iter()
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index f43f5ea..21cbb14 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -135,6 +135,7 @@
("libz-rs-sys", "Zlib"),
("normalize-line-endings", "Apache-2.0"),
("openssl", "Apache-2.0"),
+ ("ring", "Apache-2.0 AND ISC"),
("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0
("similar", "Apache-2.0"),
("sized-chunks", "MPL-2.0+"),
@@ -378,6 +379,7 @@
"serde",
"serde_derive",
"serde_json",
+ "serde_path_to_error",
"sha1",
"sha2",
"sharded-slab",
diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs
index 911d4da..8121eb0 100644
--- a/src/tools/tidy/src/ext_tool_checks.rs
+++ b/src/tools/tidy/src/ext_tool_checks.rs
@@ -50,6 +50,7 @@ pub fn check(
ci_info: &CiInfo,
librustdoc_path: &Path,
tools_path: &Path,
+ npm: &Path,
bless: bool,
extra_checks: Option<&str>,
pos_args: &[String],
@@ -61,6 +62,7 @@ pub fn check(
ci_info,
librustdoc_path,
tools_path,
+ npm,
bless,
extra_checks,
pos_args,
@@ -75,6 +77,7 @@ fn check_impl(
ci_info: &CiInfo,
librustdoc_path: &Path,
tools_path: &Path,
+ npm: &Path,
bless: bool,
extra_checks: Option<&str>,
pos_args: &[String],
@@ -293,7 +296,7 @@ macro_rules! extra_check {
}
if js_lint || js_typecheck {
- rustdoc_js::npm_install(root_path, outdir)?;
+ rustdoc_js::npm_install(root_path, outdir, npm)?;
}
if js_lint {
diff --git a/src/tools/tidy/src/ext_tool_checks/rustdoc_js.rs b/src/tools/tidy/src/ext_tool_checks/rustdoc_js.rs
index c1a62ce..7708b12 100644
--- a/src/tools/tidy/src/ext_tool_checks/rustdoc_js.rs
+++ b/src/tools/tidy/src/ext_tool_checks/rustdoc_js.rs
@@ -23,9 +23,8 @@ fn spawn_cmd(cmd: &mut Command) -> Result<Child, io::Error> {
}
/// install all js dependencies from package.json.
-pub(super) fn npm_install(root_path: &Path, outdir: &Path) -> Result<(), super::Error> {
- // FIXME(lolbinarycat): make this obey build.npm bootstrap option
- npm::install(root_path, outdir, Path::new("npm"))?;
+pub(super) fn npm_install(root_path: &Path, outdir: &Path, npm: &Path) -> Result<(), super::Error> {
+ npm::install(root_path, outdir, npm)?;
Ok(())
}
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 13b20f3..11ee2ae 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -29,6 +29,7 @@ fn main() {
let concurrency: NonZeroUsize =
FromStr::from_str(&env::args().nth(4).expect("need concurrency"))
.expect("concurrency must be a number");
+ let npm: PathBuf = env::args_os().nth(5).expect("need name/path of npm command").into();
let root_manifest = root_path.join("Cargo.toml");
let src_path = root_path.join("src");
@@ -182,6 +183,7 @@ macro_rules! check {
&ci_info,
&librustdoc_path,
&tools_path,
+ &npm,
bless,
extra_checks,
pos_args
diff --git a/tests/codegen-llvm/intrinsics/transmute-niched.rs b/tests/codegen-llvm/intrinsics/transmute-niched.rs
index 8ff5cc8..a886d9e 100644
--- a/tests/codegen-llvm/intrinsics/transmute-niched.rs
+++ b/tests/codegen-llvm/intrinsics/transmute-niched.rs
@@ -163,11 +163,8 @@ pub unsafe fn check_swap_pair(x: (char, NonZero<u32>)) -> (NonZero<u32>, char) {
pub unsafe fn check_bool_from_ordering(x: std::cmp::Ordering) -> bool {
// CHECK-NOT: icmp
// CHECK-NOT: assume
- // OPT: %0 = sub i8 %x, -1
- // OPT: %1 = icmp ule i8 %0, 2
- // OPT: call void @llvm.assume(i1 %1)
- // OPT: %2 = icmp ule i8 %x, 1
- // OPT: call void @llvm.assume(i1 %2)
+ // OPT: %0 = icmp ule i8 %x, 1
+ // OPT: call void @llvm.assume(i1 %0)
// CHECK-NOT: icmp
// CHECK-NOT: assume
// CHECK: %[[R:.+]] = trunc{{( nuw)?}} i8 %x to i1
@@ -184,9 +181,6 @@ pub unsafe fn check_bool_to_ordering(x: bool) -> std::cmp::Ordering {
// CHECK-NOT: assume
// OPT: %0 = icmp ule i8 %_0, 1
// OPT: call void @llvm.assume(i1 %0)
- // OPT: %1 = sub i8 %_0, -1
- // OPT: %2 = icmp ule i8 %1, 2
- // OPT: call void @llvm.assume(i1 %2)
// CHECK-NOT: icmp
// CHECK-NOT: assume
// CHECK: ret i8 %_0
@@ -221,3 +215,42 @@ pub unsafe fn check_ptr_to_nonnull(x: *const u8) -> NonNull<u8> {
transmute(x)
}
+
+#[repr(usize)]
+pub enum FourOrEight {
+ Four = 4,
+ Eight = 8,
+}
+
+// CHECK-LABEL: @check_nonnull_to_four_or_eight(
+#[no_mangle]
+pub unsafe fn check_nonnull_to_four_or_eight(x: NonNull<u8>) -> FourOrEight {
+ // CHECK: start
+ // CHECK-NEXT: %[[RET:.+]] = ptrtoint ptr %x to i64
+ // CHECK-NOT: icmp
+ // CHECK-NOT: assume
+ // OPT: %0 = sub i64 %[[RET]], 4
+ // OPT: %1 = icmp ule i64 %0, 4
+ // OPT: call void @llvm.assume(i1 %1)
+ // CHECK-NOT: icmp
+ // CHECK-NOT: assume
+ // CHECK: ret i64 %[[RET]]
+
+ transmute(x)
+}
+
+// CHECK-LABEL: @check_four_or_eight_to_nonnull(
+#[no_mangle]
+pub unsafe fn check_four_or_eight_to_nonnull(x: FourOrEight) -> NonNull<u8> {
+ // CHECK-NOT: icmp
+ // CHECK-NOT: assume
+ // OPT: %0 = sub i64 %x, 4
+ // OPT: %1 = icmp ule i64 %0, 4
+ // OPT: call void @llvm.assume(i1 %1)
+ // CHECK-NOT: icmp
+ // CHECK-NOT: assume
+ // CHECK: %[[RET:.+]] = getelementptr i8, ptr null, i64 %x
+ // CHECK-NEXT: ret ptr %[[RET]]
+
+ transmute(x)
+}
diff --git a/tests/crashes/121097.rs b/tests/crashes/121097.rs
deleted file mode 100644
index 65c6028..0000000
--- a/tests/crashes/121097.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ known-bug: #121097
-#[repr(simd)]
-enum Aligned {
- Zero = 0,
- One = 1,
-}
-
-fn tou8(al: Aligned) -> u8 {
- al as u8
-}
diff --git a/tests/mir-opt/building/enum_cast.bar.built.after.mir b/tests/mir-opt/building/enum_cast.bar.built.after.mir
index 72d0cf5..0dc6448 100644
--- a/tests/mir-opt/building/enum_cast.bar.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.bar.built.after.mir
@@ -5,16 +5,11 @@
let mut _0: usize;
let _2: Bar;
let mut _3: isize;
- let mut _4: u8;
- let mut _5: bool;
bb0: {
StorageLive(_2);
_2 = move _1;
_3 = discriminant(_2);
- _4 = copy _3 as u8 (IntToInt);
- _5 = Le(copy _4, const 1_u8);
- assume(move _5);
_0 = move _3 as usize (IntToInt);
StorageDead(_2);
return;
diff --git a/tests/mir-opt/building/enum_cast.boo.built.after.mir b/tests/mir-opt/building/enum_cast.boo.built.after.mir
index 91e06dc..3540a2b 100644
--- a/tests/mir-opt/building/enum_cast.boo.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.boo.built.after.mir
@@ -5,16 +5,11 @@
let mut _0: usize;
let _2: Boo;
let mut _3: u8;
- let mut _4: u8;
- let mut _5: bool;
bb0: {
StorageLive(_2);
_2 = move _1;
_3 = discriminant(_2);
- _4 = copy _3 as u8 (IntToInt);
- _5 = Le(copy _4, const 1_u8);
- assume(move _5);
_0 = move _3 as usize (IntToInt);
StorageDead(_2);
return;
diff --git a/tests/mir-opt/building/enum_cast.far.built.after.mir b/tests/mir-opt/building/enum_cast.far.built.after.mir
index 14eaf344..da34b7b 100644
--- a/tests/mir-opt/building/enum_cast.far.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.far.built.after.mir
@@ -5,16 +5,11 @@
let mut _0: isize;
let _2: Far;
let mut _3: i16;
- let mut _4: u16;
- let mut _5: bool;
bb0: {
StorageLive(_2);
_2 = move _1;
_3 = discriminant(_2);
- _4 = copy _3 as u16 (IntToInt);
- _5 = Le(copy _4, const 1_u16);
- assume(move _5);
_0 = move _3 as isize (IntToInt);
StorageDead(_2);
return;
diff --git a/tests/mir-opt/building/enum_cast.offsetty.built.after.mir b/tests/mir-opt/building/enum_cast.offsetty.built.after.mir
index 1c2acbe..b84ce0d 100644
--- a/tests/mir-opt/building/enum_cast.offsetty.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.offsetty.built.after.mir
@@ -5,20 +5,11 @@
let mut _0: u32;
let _2: NotStartingAtZero;
let mut _3: isize;
- let mut _4: u8;
- let mut _5: bool;
- let mut _6: bool;
- let mut _7: bool;
bb0: {
StorageLive(_2);
_2 = move _1;
_3 = discriminant(_2);
- _4 = copy _3 as u8 (IntToInt);
- _5 = Ge(copy _4, const 4_u8);
- _6 = Le(copy _4, const 8_u8);
- _7 = BitAnd(move _5, move _6);
- assume(move _7);
_0 = move _3 as u32 (IntToInt);
StorageDead(_2);
return;
diff --git a/tests/mir-opt/building/enum_cast.rs b/tests/mir-opt/building/enum_cast.rs
index 4fb9a27..eaf5537 100644
--- a/tests/mir-opt/building/enum_cast.rs
+++ b/tests/mir-opt/building/enum_cast.rs
@@ -4,6 +4,13 @@
// EMIT_MIR enum_cast.boo.built.after.mir
// EMIT_MIR enum_cast.far.built.after.mir
+// Previously MIR building included range `Assume`s in the MIR statements,
+// which these tests demonstrated, but now that we have range metadata on
+// parameters in LLVM (in addition to !range metadata on loads) the impact
+// of the extra volume of MIR is worse than its value.
+// Thus these are now about the discriminant type and the cast type,
+// both of which might be different from the backend type of the tag.
+
enum Foo {
A,
}
diff --git a/tests/mir-opt/building/enum_cast.signy.built.after.mir b/tests/mir-opt/building/enum_cast.signy.built.after.mir
index 39b6dfa..503c506 100644
--- a/tests/mir-opt/building/enum_cast.signy.built.after.mir
+++ b/tests/mir-opt/building/enum_cast.signy.built.after.mir
@@ -5,20 +5,11 @@
let mut _0: i16;
let _2: SignedAroundZero;
let mut _3: i16;
- let mut _4: u16;
- let mut _5: bool;
- let mut _6: bool;
- let mut _7: bool;
bb0: {
StorageLive(_2);
_2 = move _1;
_3 = discriminant(_2);
- _4 = copy _3 as u16 (IntToInt);
- _5 = Ge(copy _4, const 65534_u16);
- _6 = Le(copy _4, const 2_u16);
- _7 = BitOr(move _5, move _6);
- assume(move _7);
_0 = move _3 as i16 (IntToInt);
StorageDead(_2);
return;
diff --git a/tests/run-make/rustdoc-target-spec-json-path/target.json b/tests/run-make/rustdoc-target-spec-json-path/target.json
index c478f11..d7e4cac 100644
--- a/tests/run-make/rustdoc-target-spec-json-path/target.json
+++ b/tests/run-make/rustdoc-target-spec-json-path/target.json
@@ -6,7 +6,6 @@
"dynamic-linking": true,
"env": "gnu",
"executables": true,
- "has-elf-tls": true,
"has-rpath": true,
"linker-is-gnu": true,
"llvm-target": "x86_64-unknown-linux-gnu",
diff --git a/tests/run-make/target-specs/endianness-mismatch.json b/tests/run-make/target-specs/endianness-mismatch.json
index 431053e..cc03bec 100644
--- a/tests/run-make/target-specs/endianness-mismatch.json
+++ b/tests/run-make/target-specs/endianness-mismatch.json
@@ -5,7 +5,6 @@
"llvm-target": "x86_64-unknown-linux-gnu",
"target-endian": "big",
"target-pointer-width": "64",
- "target-c-int-width": "32",
"arch": "x86_64",
"os": "linux"
}
diff --git a/tests/run-make/target-specs/my-awesome-platform.json b/tests/run-make/target-specs/my-awesome-platform.json
index 1673ef7..d41038b 100644
--- a/tests/run-make/target-specs/my-awesome-platform.json
+++ b/tests/run-make/target-specs/my-awesome-platform.json
@@ -4,8 +4,6 @@
"llvm-target": "i686-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "32",
- "target-c-int-width": "32",
"arch": "x86",
- "os": "linux",
- "morestack": false
+ "os": "linux"
}
diff --git a/tests/run-make/target-specs/my-incomplete-platform.json b/tests/run-make/target-specs/my-incomplete-platform.json
index ceaa25c..8bdc410 100644
--- a/tests/run-make/target-specs/my-incomplete-platform.json
+++ b/tests/run-make/target-specs/my-incomplete-platform.json
@@ -3,8 +3,6 @@
"linker-flavor": "gcc",
"target-endian": "little",
"target-pointer-width": "32",
- "target-c-int-width": "32",
"arch": "x86",
- "os": "foo",
- "morestack": false
+ "os": "foo"
}
diff --git a/tests/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json b/tests/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json
index 0cafce1..27833f1 100644
--- a/tests/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json
+++ b/tests/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json
@@ -5,8 +5,6 @@
"llvm-target": "x86_64-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "64",
- "target-c-int-width": "32",
"arch": "x86_64",
- "os": "linux",
- "morestack": false
+ "os": "linux"
}
diff --git a/tests/run-make/target-specs/require-explicit-cpu.json b/tests/run-make/target-specs/require-explicit-cpu.json
index 5cbb957..9744bca 100644
--- a/tests/run-make/target-specs/require-explicit-cpu.json
+++ b/tests/run-make/target-specs/require-explicit-cpu.json
@@ -4,7 +4,6 @@
"llvm-target": "i686-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "32",
- "target-c-int-width": "32",
"arch": "x86",
"os": "linux",
"need-explicit-cpu": true
diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs
index 9184e5f..7e56558 100644
--- a/tests/run-make/target-specs/rmake.rs
+++ b/tests/run-make/target-specs/rmake.rs
@@ -8,8 +8,6 @@
use run_make_support::{diff, rfs, rustc};
fn main() {
- rustc().input("foo.rs").target("my-awesome-platform.json").crate_type("lib").emit("asm").run();
- assert!(!rfs::read_to_string("foo.s").contains("morestack"));
rustc()
.input("foo.rs")
.target("my-invalid-platform.json")
@@ -19,7 +17,7 @@ fn main() {
.input("foo.rs")
.target("my-incomplete-platform.json")
.run_fail()
- .assert_stderr_contains("Field llvm-target");
+ .assert_stderr_contains("missing field `llvm-target`");
rustc()
.env("RUST_TARGET_PATH", ".")
.input("foo.rs")
diff --git a/tests/ui/SUMMARY.md b/tests/ui/README.md
similarity index 100%
rename from tests/ui/SUMMARY.md
rename to tests/ui/README.md
diff --git a/tests/ui/asm/named-asm-labels.rs b/tests/ui/asm/named-asm-labels.rs
index 996fb82..e78553f 100644
--- a/tests/ui/asm/named-asm-labels.rs
+++ b/tests/ui/asm/named-asm-labels.rs
@@ -171,12 +171,10 @@ fn main() {
}
}
-// Trigger on naked fns too, even though they can't be inlined, reusing a
-// label or LTO can cause labels to break
+// Don't trigger on naked functions.
#[unsafe(naked)]
pub extern "C" fn foo() -> i32 {
naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1)
- //~^ ERROR avoid using named labels
}
// Make sure that non-naked attributes *do* still let the lint happen
@@ -190,7 +188,18 @@ pub extern "C" fn bar() {
pub extern "C" fn aaa() {
fn _local() {}
- naked_asm!(".Laaa: nop; ret;") //~ ERROR avoid using named labels
+ naked_asm!(".Laaa: nop; ret;")
+}
+
+#[unsafe(naked)]
+pub extern "C" fn bbb<'a>(a: &'a u32) {
+ naked_asm!(".Lbbb: nop; ret;")
+}
+
+#[unsafe(naked)]
+pub extern "C" fn ccc<T>(a: &T) {
+ naked_asm!(".Lccc: nop; ret;")
+ //~^ ERROR avoid using named labels
}
pub fn normal() {
@@ -200,7 +209,7 @@ fn _local1() {}
pub extern "C" fn bbb() {
fn _very_local() {}
- naked_asm!(".Lbbb: nop; ret;") //~ ERROR avoid using named labels
+ naked_asm!(".Lbbb: nop; ret;")
}
fn _local2() {}
@@ -230,3 +239,10 @@ extern "C" fn _nested() {
// Don't trigger on global asm
global_asm!("aaaaaaaa: nop");
+
+trait Foo {
+ #[unsafe(naked)]
+ extern "C" fn bbb<'a>(a: &'a u32) {
+ naked_asm!(".Lbbb: nop; ret;") //~ ERROR avoid using named labels
+ }
+}
diff --git a/tests/ui/asm/named-asm-labels.stderr b/tests/ui/asm/named-asm-labels.stderr
index cd7e7a0..9ba9e14 100644
--- a/tests/ui/asm/named-asm-labels.stderr
+++ b/tests/ui/asm/named-asm-labels.stderr
@@ -475,16 +475,7 @@
| ^^^^^^^^^^^^^^^^
error: avoid using named labels in inline assembly
- --> $DIR/named-asm-labels.rs:178:17
- |
-LL | naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1)
- | ^^^^^
- |
- = help: only local labels of the form `<number>:` should be used in inline asm
- = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
-
-error: avoid using named labels in inline assembly
- --> $DIR/named-asm-labels.rs:185:20
+ --> $DIR/named-asm-labels.rs:183:20
|
LL | unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noreturn)) }
| ^^^^^
@@ -493,25 +484,16 @@
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
error: avoid using named labels in inline assembly
- --> $DIR/named-asm-labels.rs:193:17
+ --> $DIR/named-asm-labels.rs:201:17
|
-LL | naked_asm!(".Laaa: nop; ret;")
+LL | naked_asm!(".Lccc: nop; ret;")
| ^^^^^
|
= help: only local labels of the form `<number>:` should be used in inline asm
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
error: avoid using named labels in inline assembly
- --> $DIR/named-asm-labels.rs:203:21
- |
-LL | naked_asm!(".Lbbb: nop; ret;")
- | ^^^^^
- |
- = help: only local labels of the form `<number>:` should be used in inline asm
- = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
-
-error: avoid using named labels in inline assembly
- --> $DIR/named-asm-labels.rs:212:15
+ --> $DIR/named-asm-labels.rs:221:15
|
LL | asm!("closure1: nop");
| ^^^^^^^^
@@ -520,7 +502,7 @@
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
error: avoid using named labels in inline assembly
- --> $DIR/named-asm-labels.rs:216:15
+ --> $DIR/named-asm-labels.rs:225:15
|
LL | asm!("closure2: nop");
| ^^^^^^^^
@@ -529,7 +511,7 @@
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
error: avoid using named labels in inline assembly
- --> $DIR/named-asm-labels.rs:226:19
+ --> $DIR/named-asm-labels.rs:235:19
|
LL | asm!("closure3: nop");
| ^^^^^^^^
@@ -537,5 +519,14 @@
= help: only local labels of the form `<number>:` should be used in inline asm
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
-error: aborting due to 56 previous errors; 1 warning emitted
+error: avoid using named labels in inline assembly
+ --> $DIR/named-asm-labels.rs:246:21
+ |
+LL | naked_asm!(".Lbbb: nop; ret;")
+ | ^^^^^
+ |
+ = help: only local labels of the form `<number>:` should be used in inline asm
+ = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
+
+error: aborting due to 55 previous errors; 1 warning emitted
diff --git a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs
index c8bb0eb..49e46f4 100644
--- a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs
+++ b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.rs
@@ -1,4 +1,4 @@
-// Regression test for issue #105056.
+// issue: <https://github.com/rust-lang/rust/issues/105056>
//@ edition: 2021
fn f(_: impl Trait<T = Copy>) {}
@@ -23,4 +23,11 @@ fn h(_: impl Trait<T<> = 'static + for<'a> Fn(&'a ())>) {}
trait Trait { type T; }
+// Don't suggest assoc ty bounds when we have parenthesized args (the underlying assoc type
+// binding `Output` isn't introduced by `=` but by `->`, suggesting `:` wouldn't be valid).
+// issue: <https://github.com/rust-lang/rust/issues/140543>
+fn i(_: impl Fn() -> std::fmt::Debug) {}
+//~^ ERROR expected a type, found a trait
+//~| HELP you can add the `dyn` keyword if you want a trait object
+
fn main() {}
diff --git a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr
index 6eb8fab..ea9f25f 100644
--- a/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr
+++ b/tests/ui/associated-type-bounds/suggest-assoc-ty-bound-on-eq-bound.stderr
@@ -57,6 +57,17 @@
LL | type Obj = dyn Trait<T = dyn Clone>;
| +++
-error: aborting due to 4 previous errors
+error[E0782]: expected a type, found a trait
+ --> $DIR/suggest-assoc-ty-bound-on-eq-bound.rs:29:22
+ |
+LL | fn i(_: impl Fn() -> std::fmt::Debug) {}
+ | ^^^^^^^^^^^^^^^
+ |
+help: you can add the `dyn` keyword if you want a trait object
+ |
+LL | fn i(_: impl Fn() -> dyn std::fmt::Debug) {}
+ | +++
+
+error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0782`.
diff --git a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
index 03fa220..3fe1431 100644
--- a/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
+++ b/tests/ui/async-await/async-closures/closure-shim-borrowck-error.stderr
@@ -1,14 +1,13 @@
error[E0507]: cannot move out of `x` which is behind a mutable reference
--> $DIR/closure-shim-borrowck-error.rs:11:18
|
+LL | fn hello(x: Ty) {
+ | -- move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
LL | needs_fn_mut(async || {
| ^^^^^^^^ `x` is moved here
LL |
LL | x.hello();
- | -
- | |
- | variable moved due to use in coroutine
- | move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
+ | - variable moved due to use in coroutine
|
note: if `Ty` implemented `Clone`, you could clone the value
--> $DIR/closure-shim-borrowck-error.rs:17:1
diff --git a/tests/ui/async-await/async-closures/move-out-of-ref.stderr b/tests/ui/async-await/async-closures/move-out-of-ref.stderr
index 8a63515..d443dc9 100644
--- a/tests/ui/async-await/async-closures/move-out-of-ref.stderr
+++ b/tests/ui/async-await/async-closures/move-out-of-ref.stderr
@@ -1,8 +1,11 @@
error[E0507]: cannot move out of `*x` which is behind a shared reference
--> $DIR/move-out-of-ref.rs:9:9
|
+LL | fn hello(x: &Ty) {
+ | --- move occurs because `*x` has type `Ty`, which does not implement the `Copy` trait
+LL | let c = async || {
LL | *x;
- | ^^ move occurs because `*x` has type `Ty`, which does not implement the `Copy` trait
+ | ^^ `*x` is moved here
|
note: if `Ty` implemented `Clone`, you could clone the value
--> $DIR/move-out-of-ref.rs:5:1
diff --git a/tests/ui/backtrace/std-backtrace.rs b/tests/ui/backtrace/std-backtrace.rs
index 7ccbd46..b81bdee 100644
--- a/tests/ui/backtrace/std-backtrace.rs
+++ b/tests/ui/backtrace/std-backtrace.rs
@@ -13,9 +13,9 @@
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() >= 2 && args[1] == "force" {
- println!("stack backtrace:\n{}", std::backtrace::Backtrace::force_capture());
+ println!("{}", std::backtrace::Backtrace::force_capture());
} else if args.len() >= 2 {
- println!("stack backtrace:\n{}", std::backtrace::Backtrace::capture());
+ println!("{}", std::backtrace::Backtrace::capture());
} else {
runtest(&args[0]);
println!("test ok");
@@ -28,7 +28,6 @@ fn runtest(me: &str) {
let p = Command::new(me).arg("a").env("RUST_BACKTRACE", "1").output().unwrap();
assert!(p.status.success());
- assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n"));
assert!(String::from_utf8_lossy(&p.stdout).contains("backtrace::main"));
let p = Command::new(me).arg("a").env("RUST_BACKTRACE", "0").output().unwrap();
@@ -46,7 +45,6 @@ fn runtest(me: &str) {
.output()
.unwrap();
assert!(p.status.success());
- assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n"));
let p = Command::new(me)
.arg("a")
@@ -64,9 +62,7 @@ fn runtest(me: &str) {
.output()
.unwrap();
assert!(p.status.success());
- assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n"));
let p = Command::new(me).arg("force").output().unwrap();
assert!(p.status.success());
- assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n"));
}
diff --git a/tests/ui/borrowck/borrowck-in-static.stderr b/tests/ui/borrowck/borrowck-in-static.stderr
index 745b02a..9bcf64d 100644
--- a/tests/ui/borrowck/borrowck-in-static.stderr
+++ b/tests/ui/borrowck/borrowck-in-static.stderr
@@ -2,9 +2,11 @@
--> $DIR/borrowck-in-static.rs:5:17
|
LL | let x = Box::new(0);
- | - captured outer variable
+ | - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | Box::new(|| x)
- | -- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | -- ^ `x` is moved here
| |
| captured by this `Fn` closure
|
diff --git a/tests/ui/borrowck/borrowck-move-by-capture.stderr b/tests/ui/borrowck/borrowck-move-by-capture.stderr
index 58d5e90..732af15 100644
--- a/tests/ui/borrowck/borrowck-move-by-capture.stderr
+++ b/tests/ui/borrowck/borrowck-move-by-capture.stderr
@@ -2,14 +2,14 @@
--> $DIR/borrowck-move-by-capture.rs:9:29
|
LL | let bar: Box<_> = Box::new(3);
- | --- captured outer variable
+ | --- ------ move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | let _g = to_fn_mut(|| {
| -- captured by this `FnMut` closure
LL | let _h = to_fn_once(move || -> isize { *bar });
- | ^^^^^^^^^^^^^^^^ ----
- | | |
- | | variable moved due to use in closure
- | | move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
+ | ^^^^^^^^^^^^^^^^ ---- variable moved due to use in closure
+ | |
| `bar` is moved here
|
help: consider cloning the value before moving it into the closure
diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
index 4e19fd8..c559230 100644
--- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
+++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
@@ -4,7 +4,7 @@
LL | let sfoo: *mut Foo = &mut SFOO;
| ^^^^^^^^^ mutable reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw mut` instead to create a raw pointer
diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr
index 603055b..af65deb 100644
--- a/tests/ui/borrowck/issue-103624.stderr
+++ b/tests/ui/borrowck/issue-103624.stderr
@@ -2,13 +2,16 @@
--> $DIR/issue-103624.rs:16:13
|
LL | async fn foo(&self) {
- | ----- captured outer variable
+ | -----
+ | |
+ | captured outer variable
+ | move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
LL | let bar = self.b.bar().await;
LL | spawn_blocking(move || {
| ------- captured by this `Fn` closure
LL |
LL | self.b;
- | ^^^^^^ move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
+ | ^^^^^^ `self.b` is moved here
|
note: if `StructB` implemented `Clone`, you could clone the value
--> $DIR/issue-103624.rs:23:1
diff --git a/tests/ui/cfg/conditional-compile-arch.rs b/tests/ui/cfg/conditional-compile-arch.rs
index 594d934..f168054 100644
--- a/tests/ui/cfg/conditional-compile-arch.rs
+++ b/tests/ui/cfg/conditional-compile-arch.rs
@@ -38,3 +38,6 @@ pub fn main() { }
#[cfg(target_arch = "loongarch64")]
pub fn main() { }
+
+#[cfg(target_arch = "arm64ec")]
+pub fn main() { }
diff --git a/tests/ui/check-cfg/my-awesome-platform.json b/tests/ui/check-cfg/my-awesome-platform.json
index 03b08b7..4c16d06 100644
--- a/tests/ui/check-cfg/my-awesome-platform.json
+++ b/tests/ui/check-cfg/my-awesome-platform.json
@@ -4,7 +4,6 @@
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
- "target-c-int-width": "32",
"os": "ericos",
"linker-flavor": "ld.lld",
"linker": "rust-lld",
diff --git a/tests/ui/closures/2229_closure_analysis/issue-90465.stderr b/tests/ui/closures/2229_closure_analysis/issue-90465.stderr
index ccca247..94bbd79 100644
--- a/tests/ui/closures/2229_closure_analysis/issue-90465.stderr
+++ b/tests/ui/closures/2229_closure_analysis/issue-90465.stderr
@@ -10,7 +10,7 @@
LL | }
| - in Rust 2018, `f0` is dropped here along with the closure, but in Rust 2021 `f0` is not part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/issue-90465.rs:3:9
|
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
index fdcada4..b981ef6 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr
@@ -7,7 +7,7 @@
LL | *fptr.0 = 20;
| ------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0`
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/auto_traits.rs:2:9
|
@@ -34,7 +34,7 @@
LL | *fptr.0.0 = 20;
| --------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0.0`
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `fptr` to be fully captured
|
LL ~ thread::spawn(move || { let _ = &fptr; unsafe {
@@ -56,7 +56,7 @@
LL | }
| - in Rust 2018, `f` is dropped here, but in Rust 2021, only `f.1` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `f` to be fully captured
|
LL ~ let c = || {
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr b/tests/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
index bb17e3a..c49b1d2 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr
@@ -15,7 +15,7 @@
LL | | });
| |______- in this macro invocation
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/closure-body-macro-fragment.rs:4:9
|
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr b/tests/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
index a0795c1..3381b9e 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr
@@ -10,7 +10,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/insignificant_drop_attr_migrations.rs:3:9
|
@@ -34,7 +34,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = move || {
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/macro.stderr b/tests/ui/closures/2229_closure_analysis/migrations/macro.stderr
index 7ea5136..7d90b7b 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/macro.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/macro.stderr
@@ -7,7 +7,7 @@
LL | }
| - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/macro.rs:5:9
|
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr b/tests/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
index 9452648..7d937f5 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr
@@ -10,7 +10,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/migrations_rustfix.rs:2:9
|
@@ -31,7 +31,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL | let c = || { let _ = &t; t.0 };
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/tests/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
index 2b76dec..6a9266e 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr
@@ -10,7 +10,7 @@
LL | f.0()
| --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.0`
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/mir_calls_to_shims.rs:4:9
|
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
index 138778f..81ffe86 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr
@@ -13,7 +13,7 @@
LL | }
| - in Rust 2018, `f2` is dropped here, but in Rust 2021, only `f2.1` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/multi_diagnostics.rs:2:9
|
@@ -34,7 +34,7 @@
LL | let _f_1 = f1.0;
| ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.0`
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `f1` to be fully captured
|
LL ~ let c = || {
@@ -56,7 +56,7 @@
LL | let _f_2 = f1.2;
| ---- in Rust 2018, this closure captures all of `f1`, but in Rust 2021, it will only capture `f1.2`
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `f1` to be fully captured
|
LL ~ let c = || {
@@ -81,7 +81,7 @@
| in Rust 2018, `f1` is dropped here, but in Rust 2021, only `f1.0` will be dropped here as part of the closure
| in Rust 2018, `f1` is dropped here, but in Rust 2021, only `f1.1` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `f1` to be fully captured
|
LL ~ let c = || {
@@ -104,7 +104,7 @@
LL | *fptr2.0 = 20;
| -------- in Rust 2018, this closure captures all of `fptr2`, but in Rust 2021, it will only capture `fptr2.0`
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `fptr1`, `fptr2` to be fully captured
|
LL ~ thread::spawn(move || { let _ = (&fptr1, &fptr2); unsafe {
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/precise.stderr b/tests/ui/closures/2229_closure_analysis/migrations/precise.stderr
index eff26a4..5fb7675 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/precise.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/precise.stderr
@@ -10,7 +10,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/precise.rs:3:9
|
@@ -44,7 +44,7 @@
| in Rust 2018, `u` is dropped here, but in Rust 2021, only `u.0.1` will be dropped here as part of the closure
| in Rust 2018, `u` is dropped here, but in Rust 2021, only `u.1.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `u` to be fully captured
|
LL ~ let c = || {
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/tests/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
index 54ad20f..3f4d38a 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr
@@ -20,7 +20,7 @@
| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
| in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/significant_drop.rs:2:9
|
@@ -50,7 +50,7 @@
| in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t`, `t1` to be fully captured
|
LL ~ let c = || {
@@ -69,7 +69,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = || {
@@ -88,7 +88,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = || {
@@ -107,7 +107,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = || {
@@ -126,7 +126,7 @@
LL | }
| - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t` to be fully captured
|
LL ~ let c = || {
@@ -150,7 +150,7 @@
| in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.1` will be dropped here as part of the closure
| in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.1` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `t1`, `t` to be fully captured
|
LL ~ let c = move || {
@@ -169,7 +169,7 @@
LL | }
| - in Rust 2018, `tuple` is dropped here, but in Rust 2021, only `tuple.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `tuple` to be fully captured
|
LL ~ let c = || {
@@ -188,7 +188,7 @@
LL | };
| - in Rust 2018, `tuple` is dropped here, but in Rust 2021, only `tuple.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `tuple` to be fully captured
|
LL ~ let c = || {
@@ -204,7 +204,7 @@
LL | }
| - in Rust 2018, `tup` is dropped here, but in Rust 2021, only `tup.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
help: add a dummy let to cause `tup` to be fully captured
|
LL | let _c = || { let _ = &tup; tup.0 };
diff --git a/tests/ui/codegen/mismatched-data-layout.json b/tests/ui/codegen/mismatched-data-layout.json
index 7adc883..f8c510c 100644
--- a/tests/ui/codegen/mismatched-data-layout.json
+++ b/tests/ui/codegen/mismatched-data-layout.json
@@ -4,7 +4,6 @@
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
- "target-c-int-width": "32",
"os": "none",
"linker-flavor": "ld.lld",
"linker": "rust-lld",
diff --git a/tests/ui/codegen/mismatched-data-layouts.rs b/tests/ui/codegen/mismatched-data-layouts.rs
index 6428b8c..ea14571 100644
--- a/tests/ui/codegen/mismatched-data-layouts.rs
+++ b/tests/ui/codegen/mismatched-data-layouts.rs
@@ -5,6 +5,7 @@
//@ compile-flags: --crate-type=lib --target={{src-base}}/codegen/mismatched-data-layout.json -Z unstable-options
//@ normalize-stderr: "`, `[A-Za-z0-9-:]*`" -> "`, `normalized data layout`"
//@ normalize-stderr: "layout, `[A-Za-z0-9-:]*`" -> "layout, `normalized data layout`"
+//@ normalize-stderr: "`mismatched-data-layout-\d+`" -> "`mismatched-data-layout-<hash>`"
#![feature(lang_items, no_core, auto_traits)]
#![no_core]
diff --git a/tests/ui/codegen/mismatched-data-layouts.stderr b/tests/ui/codegen/mismatched-data-layouts.stderr
index b7d5d82..d111756 100644
--- a/tests/ui/codegen/mismatched-data-layouts.stderr
+++ b/tests/ui/codegen/mismatched-data-layouts.stderr
@@ -1,4 +1,4 @@
-error: data-layout for target `mismatched-data-layout-7193370089426056427`, `normalized data layout`, differs from LLVM target's `x86_64-unknown-none-gnu` default layout, `normalized data layout`
+error: data-layout for target `mismatched-data-layout-<hash>`, `normalized data layout`, differs from LLVM target's `x86_64-unknown-none-gnu` default layout, `normalized data layout`
error: aborting due to 1 previous error
diff --git a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr
index 3553a18..b3ccd24 100644
--- a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr
+++ b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
= note: `#[warn(non_fmt_panics)]` on by default
help: add a "{}" format string to `Display` the message
|
diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr
index 1bb5604..e8bed6d 100644
--- a/tests/ui/consts/const_let_assign2.stderr
+++ b/tests/ui/consts/const_let_assign2.stderr
@@ -4,7 +4,7 @@
LL | let ptr = unsafe { &mut BB };
| ^^^^^^^ mutable reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw mut` instead to create a raw pointer
diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.stderr b/tests/ui/consts/const_refs_to_static-ice-121413.stderr
index 1263dee..e354110 100644
--- a/tests/ui/consts/const_refs_to_static-ice-121413.stderr
+++ b/tests/ui/consts/const_refs_to_static-ice-121413.stderr
@@ -16,7 +16,7 @@
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/did_you_mean/bad-assoc-ty.edition2015.stderr b/tests/ui/did_you_mean/bad-assoc-ty.edition2015.stderr
index ed6e5c3..416ff35 100644
--- a/tests/ui/did_you_mean/bad-assoc-ty.edition2015.stderr
+++ b/tests/ui/did_you_mean/bad-assoc-ty.edition2015.stderr
@@ -186,7 +186,7 @@
| ^^^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/drop/drop-order-comparisons.e2021.stderr b/tests/ui/drop/drop-order-comparisons.e2021.stderr
index 15a3f27..d928403 100644
--- a/tests/ui/drop/drop-order-comparisons.e2021.stderr
+++ b/tests/ui/drop/drop-order-comparisons.e2021.stderr
@@ -27,7 +27,7 @@
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#3` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -75,7 +75,7 @@
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -107,7 +107,7 @@
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -139,7 +139,7 @@
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -171,7 +171,7 @@
| `#1` will be dropped later as of Edition 2024
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -193,7 +193,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -223,7 +223,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -252,7 +252,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -281,7 +281,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -310,7 +310,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -339,7 +339,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -368,7 +368,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -397,7 +397,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -426,7 +426,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
@@ -455,7 +455,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/drop-order-comparisons.rs:504:1
|
diff --git a/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr
index 0d6974d..5f04273 100644
--- a/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr
+++ b/tests/ui/drop/lint-if-let-rescope-gated.edition2021.stderr
@@ -7,7 +7,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope-gated.rs:14:1
|
diff --git a/tests/ui/drop/lint-if-let-rescope-with-macro.stderr b/tests/ui/drop/lint-if-let-rescope-with-macro.stderr
index a0afb8e..63e30f1 100644
--- a/tests/ui/drop/lint-if-let-rescope-with-macro.stderr
+++ b/tests/ui/drop/lint-if-let-rescope-with-macro.stderr
@@ -14,7 +14,7 @@
| |_____- in this macro invocation
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope-with-macro.rs:22:1
|
diff --git a/tests/ui/drop/lint-if-let-rescope.stderr b/tests/ui/drop/lint-if-let-rescope.stderr
index ca2416e..7cab733 100644
--- a/tests/ui/drop/lint-if-let-rescope.stderr
+++ b/tests/ui/drop/lint-if-let-rescope.stderr
@@ -7,7 +7,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -47,7 +47,7 @@
| -------- this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -89,7 +89,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -120,7 +120,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -146,7 +146,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -172,7 +172,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -198,7 +198,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
note: value invokes this custom destructor
--> $DIR/lint-if-let-rescope.rs:11:1
|
@@ -224,7 +224,7 @@
| this value has a significant drop implementation which may observe a major change in drop order and requires your discretion
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-if-let-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html>
help: the value is now dropped here in Edition 2024
--> $DIR/lint-if-let-rescope.rs:97:51
|
diff --git a/tests/ui/drop/lint-tail-expr-drop-order-borrowck.stderr b/tests/ui/drop/lint-tail-expr-drop-order-borrowck.stderr
index a55e366..2eeda8a 100644
--- a/tests/ui/drop/lint-tail-expr-drop-order-borrowck.stderr
+++ b/tests/ui/drop/lint-tail-expr-drop-order-borrowck.stderr
@@ -7,7 +7,7 @@
| this temporary value will be dropped at the end of the block
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: the lint level is defined here
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:6:9
|
@@ -23,7 +23,7 @@
| this temporary value will be dropped at the end of the block
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
error: relative drop order changing in Rust 2024
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:31:9
@@ -35,7 +35,7 @@
| borrow later used here
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
error: relative drop order changing in Rust 2024
--> $DIR/lint-tail-expr-drop-order-borrowck.rs:43:9
@@ -46,7 +46,7 @@
| borrow later used by call
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
error: aborting due to 4 previous errors
diff --git a/tests/ui/drop/lint-tail-expr-drop-order.stderr b/tests/ui/drop/lint-tail-expr-drop-order.stderr
index e124e98..c69c58a 100644
--- a/tests/ui/drop/lint-tail-expr-drop-order.stderr
+++ b/tests/ui/drop/lint-tail-expr-drop-order.stderr
@@ -17,7 +17,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -54,7 +54,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -86,7 +86,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -118,7 +118,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -145,7 +145,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
error: relative drop order changing in Rust 2024
@@ -167,7 +167,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
@@ -199,7 +199,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:193:5
|
@@ -231,7 +231,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#1` invokes this custom destructor
--> $DIR/lint-tail-expr-drop-order.rs:10:1
|
diff --git a/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr b/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
index 7bf452e..9497718 100644
--- a/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
+++ b/tests/ui/drop/tail_expr_drop_order-on-coroutine-unwind.stderr
@@ -23,7 +23,7 @@
| - now the temporary value is dropped here, before the local variables in the block or statement
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/temporary-tail-expr-scope.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>
note: `#2` invokes this custom destructor
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:9:1
|
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
index b811ef4..687799c 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-2.old.stderr
@@ -5,7 +5,7 @@
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
index 8b4f3f5..4cfac94 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning-3.old.stderr
@@ -5,7 +5,7 @@
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | trait B { fn f(a: A) -> dyn A; }
@@ -32,7 +32,7 @@
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | trait A { fn g(b: dyn B) -> B; }
@@ -45,7 +45,7 @@
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | trait A { fn g(b: B) -> dyn B; }
@@ -58,7 +58,7 @@
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -100,7 +100,7 @@
| ^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/dyn-compatibility/avoid-ice-on-warning.old.stderr b/tests/ui/dyn-compatibility/avoid-ice-on-warning.old.stderr
index dbfe91e..4645b35 100644
--- a/tests/ui/dyn-compatibility/avoid-ice-on-warning.old.stderr
+++ b/tests/ui/dyn-compatibility/avoid-ice-on-warning.old.stderr
@@ -23,7 +23,7 @@
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr
index 7be6cb0..3cbdd19 100644
--- a/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr
+++ b/tests/ui/dyn-compatibility/bare-trait-dont-suggest-dyn.old.stderr
@@ -5,7 +5,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/bare-trait-dont-suggest-dyn.rs:5:9
|
diff --git a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
index b930815..b034c5d 100644
--- a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
+++ b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/dyn-2018-edition-lint.rs:2:8
|
@@ -23,7 +23,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
@@ -36,7 +36,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let _x: &dyn SomeTrait = todo!();
diff --git a/tests/ui/dyn-keyword/dyn-angle-brackets.stderr b/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
index 6a29dab..3006963 100644
--- a/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
+++ b/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/dyn-angle-brackets.rs:4:9
|
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
index 6b84a64..e30c0ad 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
@@ -5,7 +5,7 @@
| ^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:22:17
@@ -25,7 +25,7 @@
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:37:5
@@ -44,7 +44,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `(): From<!>` will fail
--> $DIR/never-type-fallback-breaking.rs:50:5
@@ -63,7 +63,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:62:19
@@ -82,7 +82,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:76:17
@@ -104,7 +104,7 @@
| ^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:22:17
@@ -125,7 +125,7 @@
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:37:5
@@ -146,7 +146,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `(): From<!>` will fail
--> $DIR/never-type-fallback-breaking.rs:50:5
@@ -167,7 +167,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:62:19
@@ -188,7 +188,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/never-type-fallback-breaking.rs:76:17
diff --git a/tests/ui/entry-point/auxiliary/main_functions.rs b/tests/ui/entry-point/auxiliary/main_functions.rs
index cc7992a..ab4a09b 100644
--- a/tests/ui/entry-point/auxiliary/main_functions.rs
+++ b/tests/ui/entry-point/auxiliary/main_functions.rs
@@ -1 +1,4 @@
pub fn boilerplate() {}
+
+#[inline]
+pub fn local_codegen() {}
diff --git a/tests/ui/entry-point/imported_main_local_codegen.rs b/tests/ui/entry-point/imported_main_local_codegen.rs
new file mode 100644
index 0000000..1e46c10
--- /dev/null
+++ b/tests/ui/entry-point/imported_main_local_codegen.rs
@@ -0,0 +1,11 @@
+//@ run-pass
+//@ aux-build:main_functions.rs
+//@ compile-flags: -Ccodegen-units=1024
+
+// This is a regression test for https://github.com/rust-lang/rust/issues/144052.
+// Entrypoint functions call each other in ways that CGU partitioning doesn't know about. So there
+// is a special check to not internalize any of them. But internalizing them can be okay if there
+// are few enough CGUs, so we use a lot of CGUs in this test to hit the bad case.
+
+extern crate main_functions;
+pub use main_functions::local_codegen as main;
diff --git a/tests/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs b/tests/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs
index a6e5f70..6bbafbf 100644
--- a/tests/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs
+++ b/tests/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.rs
@@ -1,8 +1,17 @@
-#![crate_type="lib"]
+#![crate_type = "lib"]
+// Test that if any variant is non-unit,
+// we need a repr.
enum Enum {
-//~^ ERROR `#[repr(inttype)]` must be specified
- Unit = 1,
- Tuple() = 2,
- Struct{} = 3,
+ //~^ ERROR `#[repr(inttype)]` must be specified
+ Unit = 1,
+ Tuple(),
+ Struct {},
+}
+
+// Test that if any non-unit variant has an explicit
+// discriminant we need a repr.
+enum Enum2 {
+ //~^ ERROR `#[repr(inttype)]` must be specified
+ Tuple() = 2,
}
diff --git a/tests/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr b/tests/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr
index 3b718c6..35c0208 100644
--- a/tests/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr
+++ b/tests/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr
@@ -1,9 +1,23 @@
-error[E0732]: `#[repr(inttype)]` must be specified
- --> $DIR/arbitrary_enum_discriminant-no-repr.rs:3:1
+error[E0732]: `#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants
+ --> $DIR/arbitrary_enum_discriminant-no-repr.rs:5:1
|
LL | enum Enum {
| ^^^^^^^^^
+LL |
+LL | Unit = 1,
+ | - explicit discriminant specified here
+LL | Tuple(),
+ | ----- non-unit discriminant declared here
-error: aborting due to 1 previous error
+error[E0732]: `#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants
+ --> $DIR/arbitrary_enum_discriminant-no-repr.rs:14:1
+ |
+LL | enum Enum2 {
+ | ^^^^^^^^^^
+LL |
+LL | Tuple() = 2,
+ | - explicit discriminant on non-unit variant specified here
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0732`.
diff --git a/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr b/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr
index b980be6..f4f3e51 100644
--- a/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr
+++ b/tests/ui/ergonomic-clones/closure/rfc2229-migration.stderr
@@ -10,7 +10,7 @@
LL | }
| - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html>
note: the lint level is defined here
--> $DIR/rfc2229-migration.rs:5:9
|
diff --git a/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr
index 7f3022c..0004ea8 100644
--- a/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr
+++ b/tests/ui/errors/dynless-turbofish-e0191-issue-91997.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
index 418f9ac..46b6772 100644
--- a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
+++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.stderr b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.stderr
index 35fff9e..980dded 100644
--- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.stderr
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024-machine-applicable.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024-machine-applicable.rs:9:10
|
diff --git a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
index 3f8511a..dc9f1c2 100644
--- a/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
+++ b/tests/ui/impl-trait/precise-capturing/overcaptures-2024.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:7:10
|
@@ -29,7 +29,7 @@
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:11:16
|
@@ -48,7 +48,7 @@
| ^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:17:24
|
@@ -67,7 +67,7 @@
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:29:23
|
@@ -86,7 +86,7 @@
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:33:12
|
@@ -111,7 +111,7 @@
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:37:16
|
@@ -136,7 +136,7 @@
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:41:19
|
@@ -155,7 +155,7 @@
| ^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/rpit-lifetime-capture.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html>
note: specifically, this lifetime is in scope but not mentioned in the type's bounds
--> $DIR/overcaptures-2024.rs:45:18
|
diff --git a/tests/ui/issues/issue-28344.stderr b/tests/ui/issues/issue-28344.stderr
index 7bc9655..dfd4951 100644
--- a/tests/ui/issues/issue-28344.stderr
+++ b/tests/ui/issues/issue-28344.stderr
@@ -5,7 +5,7 @@
| ^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -25,7 +25,7 @@
| ^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let g = <dyn BitXor>::bitor;
diff --git a/tests/ui/issues/issue-39367.stderr b/tests/ui/issues/issue-39367.stderr
index df21c09..6507637 100644
--- a/tests/ui/issues/issue-39367.stderr
+++ b/tests/ui/issues/issue-39367.stderr
@@ -9,7 +9,7 @@
LL | | });
| |______________^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
diff --git a/tests/ui/issues/issue-4335.stderr b/tests/ui/issues/issue-4335.stderr
index 14b5cfa..42ac632 100644
--- a/tests/ui/issues/issue-4335.stderr
+++ b/tests/ui/issues/issue-4335.stderr
@@ -2,9 +2,11 @@
--> $DIR/issue-4335.rs:6:20
|
LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
- | - captured outer variable
+ | - ----- move occurs because `*v` has type `T`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | id(Box::new(|| *v))
- | -- ^^ move occurs because `*v` has type `T`, which does not implement the `Copy` trait
+ | -- ^^ `*v` is moved here
| |
| captured by this `FnMut` closure
|
diff --git a/tests/ui/issues/issue-58734.stderr b/tests/ui/issues/issue-58734.stderr
index e5dad00..c246d1f 100644
--- a/tests/ui/issues/issue-58734.stderr
+++ b/tests/ui/issues/issue-58734.stderr
@@ -5,7 +5,7 @@
| ^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/issues/issue-86756.stderr b/tests/ui/issues/issue-86756.stderr
index 0f68b76..b650b32 100644
--- a/tests/ui/issues/issue-86756.stderr
+++ b/tests/ui/issues/issue-86756.stderr
@@ -19,7 +19,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/iterators/into-iter-on-arrays-2018.stderr b/tests/ui/iterators/into-iter-on-arrays-2018.stderr
index d4055c7..8818ef8 100644
--- a/tests/ui/iterators/into-iter-on-arrays-2018.stderr
+++ b/tests/ui/iterators/into-iter-on-arrays-2018.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
= note: `#[warn(array_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
@@ -25,7 +25,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-2018.rs:22:43
@@ -34,7 +34,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-2018.rs:25:41
@@ -43,7 +43,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-2018.rs:32:24
@@ -52,7 +52,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
LL - for _ in [1, 2, 3].into_iter() {}
diff --git a/tests/ui/iterators/into-iter-on-arrays-lint.stderr b/tests/ui/iterators/into-iter-on-arrays-lint.stderr
index fb8fe79..a9dfa58 100644
--- a/tests/ui/iterators/into-iter-on-arrays-lint.stderr
+++ b/tests/ui/iterators/into-iter-on-arrays-lint.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
= note: `#[warn(array_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
@@ -25,7 +25,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
LL - [1, 2].into_iter();
@@ -44,7 +44,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
LL - big.into_iter();
@@ -63,7 +63,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
LL - [0u8; 33].into_iter();
@@ -82,7 +82,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-lint.rs:27:22
@@ -91,7 +91,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-lint.rs:30:19
@@ -100,7 +100,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-lint.rs:33:25
@@ -109,7 +109,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-lint.rs:37:31
@@ -118,7 +118,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-lint.rs:40:32
@@ -127,7 +127,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-lint.rs:43:29
@@ -136,7 +136,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<[T; N] as IntoIterator>::into_iter` in Rust 2021
--> $DIR/into-iter-on-arrays-lint.rs:46:35
@@ -145,7 +145,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
warning: 12 warnings emitted
diff --git a/tests/ui/iterators/into-iter-on-boxed-slices-2021.stderr b/tests/ui/iterators/into-iter-on-boxed-slices-2021.stderr
index 7a5a2be..a0c1432 100644
--- a/tests/ui/iterators/into-iter-on-boxed-slices-2021.stderr
+++ b/tests/ui/iterators/into-iter-on-boxed-slices-2021.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
= note: `#[warn(boxed_slice_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
@@ -25,7 +25,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
warning: this method call resolves to `<&Box<[T]> as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<Box<[T]> as IntoIterator>::into_iter` in Rust 2024
--> $DIR/into-iter-on-boxed-slices-2021.rs:22:57
@@ -34,7 +34,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
warning: this method call resolves to `<&Box<[T]> as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<Box<[T]> as IntoIterator>::into_iter` in Rust 2024
--> $DIR/into-iter-on-boxed-slices-2021.rs:25:55
@@ -43,7 +43,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
warning: this method call resolves to `<&Box<[T]> as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<Box<[T]> as IntoIterator>::into_iter` in Rust 2024
--> $DIR/into-iter-on-boxed-slices-2021.rs:32:48
@@ -52,7 +52,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
LL - for _ in (Box::new([1, 2, 3]) as Box<[_]>).into_iter() {}
diff --git a/tests/ui/iterators/into-iter-on-boxed-slices-lint.stderr b/tests/ui/iterators/into-iter-on-boxed-slices-lint.stderr
index 6762ed2..377455d 100644
--- a/tests/ui/iterators/into-iter-on-boxed-slices-lint.stderr
+++ b/tests/ui/iterators/into-iter-on-boxed-slices-lint.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
= note: `#[warn(boxed_slice_into_iter)]` on by default
help: use `.iter()` instead of `.into_iter()` to avoid ambiguity
|
@@ -25,7 +25,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
warning: this method call resolves to `<&Box<[T]> as IntoIterator>::into_iter` (due to backwards compatibility), but will resolve to `<Box<[T]> as IntoIterator>::into_iter` in Rust 2024
--> $DIR/into-iter-on-boxed-slices-lint.rs:16:39
@@ -34,7 +34,7 @@
| ^^^^^^^^^ help: use `.iter()` instead of `.into_iter()` to avoid ambiguity: `iter`
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
warning: 3 warnings emitted
diff --git a/tests/ui/linkage-attr/incompatible-flavor.rs b/tests/ui/linkage-attr/incompatible-flavor.rs
index 7f583f4..4711343 100644
--- a/tests/ui/linkage-attr/incompatible-flavor.rs
+++ b/tests/ui/linkage-attr/incompatible-flavor.rs
@@ -1,5 +1,5 @@
//@ compile-flags: --target=x86_64-unknown-linux-gnu -C linker-flavor=msvc --crate-type=rlib
-//@ needs-llvm-components:
+//@ needs-llvm-components: x86
#![feature(no_core)]
#![no_core]
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/empty.rs b/tests/ui/linkage-attr/raw-dylib/elf/empty.rs
new file mode 100644
index 0000000..2e48a5f
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/elf/empty.rs
@@ -0,0 +1,11 @@
+//@ only-x86_64-unknown-linux-gnu
+//@ needs-dynamic-linking
+//@ build-pass
+
+#![allow(incomplete_features)]
+#![feature(raw_dylib_elf)]
+
+#[link(name = "hack", kind = "raw-dylib")]
+unsafe extern "C" {}
+
+fn main() {}
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs b/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs
new file mode 100644
index 0000000..57492ed
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/elf/glibc-x86_64.rs
@@ -0,0 +1,80 @@
+//@ only-x86_64-unknown-linux-gnu
+//@ needs-dynamic-linking
+//@ run-pass
+//@ compile-flags: -Cpanic=abort
+//@ edition: 2024
+
+#![allow(incomplete_features)]
+#![feature(raw_dylib_elf)]
+#![no_std]
+#![no_main]
+
+use core::ffi::{c_char, c_int};
+
+extern "C" fn callback(
+ _fpath: *const c_char,
+ _sb: *const (),
+ _tflag: c_int,
+ _ftwbuf: *const (),
+) -> c_int {
+ 0
+}
+
+// `libc.so` is a linker script that provides the paths to `libc.so.6` and `libc_nonshared.a`.
+// In earlier versions of glibc, `libc_nonshared.a` provides the symbols `__libc_csu_init` and
+// `__libc_csu_fini` required by `Scrt1.o`.
+#[link(name = "c_nonshared", kind = "static")]
+unsafe extern "C" {}
+
+#[link(name = "libc.so.6", kind = "raw-dylib", modifiers = "+verbatim")]
+unsafe extern "C" {
+ #[link_name = "nftw@GLIBC_2.2.5"]
+ unsafe fn nftw_2_2_5(
+ dirpath: *const c_char,
+ f: extern "C" fn(*const c_char, *const (), c_int, *const ()) -> c_int,
+ nopenfd: c_int,
+ flags: c_int,
+ ) -> c_int;
+ #[link_name = "nftw@GLIBC_2.3.3"]
+ unsafe fn nftw_2_3_3(
+ dirpath: *const c_char,
+ f: extern "C" fn(*const c_char, *const (), c_int, *const ()) -> c_int,
+ nopenfd: c_int,
+ flags: c_int,
+ ) -> c_int;
+ #[link_name = "exit@GLIBC_2.2.5"]
+ safe fn exit(status: i32) -> !;
+ unsafe fn __libc_start_main() -> c_int;
+}
+
+#[unsafe(no_mangle)]
+extern "C" fn main() -> ! {
+ unsafe {
+ // The old `nftw` does not check whether unknown flags are set.
+ let res = nftw_2_2_5(c".".as_ptr(), callback, 20, 1 << 30);
+ assert_eq!(res, 0);
+ }
+ unsafe {
+ // The new `nftw` does.
+ let res = nftw_2_3_3(c".".as_ptr(), callback, 20, 1 << 30);
+ assert_eq!(res, -1);
+ }
+ exit(0);
+}
+
+#[cfg(not(test))]
+#[panic_handler]
+fn panic_handler(_: &core::panic::PanicInfo<'_>) -> ! {
+ exit(1);
+}
+
+#[unsafe(no_mangle)]
+extern "C" fn rust_eh_personality(
+ _version: i32,
+ _actions: i32,
+ _exception_class: u64,
+ _exception_object: *mut (),
+ _context: *mut (),
+) -> i32 {
+ exit(1);
+}
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/malformed-link-name.rs b/tests/ui/linkage-attr/raw-dylib/elf/malformed-link-name.rs
new file mode 100644
index 0000000..46e3798
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/elf/malformed-link-name.rs
@@ -0,0 +1,20 @@
+//@ only-elf
+//@ needs-dynamic-linking
+//@ check-fail
+
+#![feature(raw_dylib_elf)]
+#![allow(incomplete_features)]
+
+#[link(name = "libc.so.6", kind = "raw-dylib", modifiers = "+verbatim")]
+unsafe extern "C" {
+ #[link_name = "exit@"]
+ pub safe fn exit_0(status: i32) -> !; //~ ERROR link name must be well-formed if link kind is `raw-dylib`
+ #[link_name = "@GLIBC_2.2.5"]
+ pub safe fn exit_1(status: i32) -> !; //~ ERROR link name must be well-formed if link kind is `raw-dylib`
+ #[link_name = "ex\0it@GLIBC_2.2.5"]
+ pub safe fn exit_2(status: i32) -> !; //~ ERROR link name must be well-formed if link kind is `raw-dylib`
+ #[link_name = "exit@@GLIBC_2.2.5"]
+ pub safe fn exit_3(status: i32) -> !; //~ ERROR link name must be well-formed if link kind is `raw-dylib`
+}
+
+fn main() {}
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/malformed-link-name.stderr b/tests/ui/linkage-attr/raw-dylib/elf/malformed-link-name.stderr
new file mode 100644
index 0000000..5a979e7
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/elf/malformed-link-name.stderr
@@ -0,0 +1,26 @@
+error: link name must be well-formed if link kind is `raw-dylib`
+ --> $DIR/malformed-link-name.rs:11:5
+ |
+LL | pub safe fn exit_0(status: i32) -> !;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: link name must be well-formed if link kind is `raw-dylib`
+ --> $DIR/malformed-link-name.rs:13:5
+ |
+LL | pub safe fn exit_1(status: i32) -> !;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: link name must be well-formed if link kind is `raw-dylib`
+ --> $DIR/malformed-link-name.rs:15:5
+ |
+LL | pub safe fn exit_2(status: i32) -> !;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: link name must be well-formed if link kind is `raw-dylib`
+ --> $DIR/malformed-link-name.rs:17:5
+ |
+LL | pub safe fn exit_3(status: i32) -> !;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr
index 25f3e85..8da63a9 100644
--- a/tests/ui/lint/bare-trait-objects-path.stderr
+++ b/tests/ui/lint/bare-trait-objects-path.stderr
@@ -5,7 +5,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@
| ^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | <dyn (::Dyn)>::func();
@@ -32,7 +32,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | <dyn Dyn>::CONST;
@@ -45,7 +45,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let _: <dyn Dyn>::Ty;
diff --git a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
index a1aa29d..2be7416 100644
--- a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: requested on the command line with `--force-warn bare-trait-objects`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/lint/force-warn/cap-lints-allow.stderr b/tests/ui/lint/force-warn/cap-lints-allow.stderr
index 0d10a43..92bcde1 100644
--- a/tests/ui/lint/force-warn/cap-lints-allow.stderr
+++ b/tests/ui/lint/force-warn/cap-lints-allow.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: requested on the command line with `--force-warn bare-trait-objects`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr
index d1b764b..74b34de 100644
--- a/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr
@@ -5,7 +5,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility`
warning: 1 warning emitted
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
index d52bd67..5bfbc95 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
index 22483a3..dabf12b 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
index aa183b9..23a3a91 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/lint/inclusive-range-pattern-syntax.stderr b/tests/ui/lint/inclusive-range-pattern-syntax.stderr
index ed9fa0d..a41082b 100644
--- a/tests/ui/lint/inclusive-range-pattern-syntax.stderr
+++ b/tests/ui/lint/inclusive-range-pattern-syntax.stderr
@@ -5,7 +5,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/inclusive-range-pattern-syntax.rs:4:9
|
@@ -19,7 +19,7 @@
| ^^^^^^ help: use `..=` for an inclusive range: `&(1..=2)`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
warning: 2 warnings emitted
diff --git a/tests/ui/lint/lint-attr-everywhere-early.stderr b/tests/ui/lint/lint-attr-everywhere-early.stderr
index fac0eb4..2389b69 100644
--- a/tests/ui/lint/lint-attr-everywhere-early.stderr
+++ b/tests/ui/lint/lint-attr-everywhere-early.stderr
@@ -391,7 +391,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/lint-attr-everywhere-early.rs:138:16
|
@@ -489,7 +489,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/lint-attr-everywhere-early.rs:174:20
|
diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr
index 320e0cee8..75a7e60 100644
--- a/tests/ui/lint/static-mut-refs.e2021.stderr
+++ b/tests/ui/lint/static-mut-refs.e2021.stderr
@@ -4,7 +4,7 @@
LL | let _y = &X;
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
@@ -18,7 +18,7 @@
LL | let _y = &mut X;
| ^^^^^^ mutable reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
help: use `&raw mut` instead to create a raw pointer
|
@@ -31,7 +31,7 @@
LL | let ref _a = X;
| ^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static
@@ -40,7 +40,7 @@
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -53,7 +53,7 @@
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -66,7 +66,7 @@
LL | foo(&X);
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -79,7 +79,7 @@
LL | let _ = Z.len();
| ^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static
@@ -88,7 +88,7 @@
LL | let _ = format!("{:?}", Z);
| ^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static
@@ -97,7 +97,7 @@
LL | let _v = &A.value;
| ^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -110,7 +110,7 @@
LL | let _s = &A.s.value;
| ^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -123,7 +123,7 @@
LL | let ref _v = A.value;
| ^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a mutable reference to mutable static
@@ -135,7 +135,7 @@
LL | let _x = bar!(FOO);
| --------- in this macro invocation
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: this warning originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr
index bf7ffc6..42a96ba 100644
--- a/tests/ui/lint/static-mut-refs.e2024.stderr
+++ b/tests/ui/lint/static-mut-refs.e2024.stderr
@@ -4,7 +4,7 @@
LL | let _y = &X;
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[deny(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
@@ -18,7 +18,7 @@
LL | let _y = &mut X;
| ^^^^^^ mutable reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
help: use `&raw mut` instead to create a raw pointer
|
@@ -31,7 +31,7 @@
LL | let ref _a = X;
| ^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: creating a shared reference to mutable static
@@ -40,7 +40,7 @@
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -53,7 +53,7 @@
LL | let (_b, _c) = (&X, &Y);
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -66,7 +66,7 @@
LL | foo(&X);
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -79,7 +79,7 @@
LL | let _ = Z.len();
| ^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: creating a shared reference to mutable static
@@ -88,7 +88,7 @@
LL | let _ = format!("{:?}", Z);
| ^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: creating a shared reference to mutable static
@@ -97,7 +97,7 @@
LL | let _v = &A.value;
| ^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -110,7 +110,7 @@
LL | let _s = &A.s.value;
| ^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -123,7 +123,7 @@
LL | let ref _v = A.value;
| ^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
error: creating a mutable reference to mutable static
@@ -135,7 +135,7 @@
LL | let _x = bar!(FOO);
| --------- in this macro invocation
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/loop-match/suggest-const-item.rs b/tests/ui/loop-match/suggest-const-item.rs
new file mode 100644
index 0000000..f921b43
--- /dev/null
+++ b/tests/ui/loop-match/suggest-const-item.rs
@@ -0,0 +1,174 @@
+#![allow(incomplete_features)]
+#![feature(loop_match)]
+#![feature(generic_const_items)]
+#![crate_type = "lib"]
+
+const fn const_fn() -> i32 {
+ 1
+}
+
+#[unsafe(no_mangle)]
+fn suggest_const_block<const N: i32>() -> i32 {
+ let mut state = 0;
+ #[loop_match]
+ loop {
+ state = 'blk: {
+ match state {
+ 0 => {
+ #[const_continue]
+ break 'blk const_fn();
+ //~^ ERROR could not determine the target branch for this `#[const_continue]`
+ }
+ 1 => {
+ #[const_continue]
+ break 'blk const { const_fn() };
+ //~^ ERROR could not determine the target branch for this `#[const_continue]`
+ }
+ 2 => {
+ #[const_continue]
+ break 'blk N;
+ //~^ ERROR could not determine the target branch for this `#[const_continue]`
+ }
+ _ => {
+ #[const_continue]
+ break 'blk 1 + 1;
+ //~^ ERROR could not determine the target branch for this `#[const_continue]`
+ }
+ }
+ }
+ }
+ state
+}
+
+struct S;
+
+impl S {
+ const M: usize = 42;
+
+ fn g() {
+ let mut state = 0;
+ #[loop_match]
+ loop {
+ state = 'blk: {
+ match state {
+ 0 => {
+ #[const_continue]
+ break 'blk Self::M;
+ }
+ _ => panic!(),
+ }
+ }
+ }
+ }
+}
+
+trait T {
+ const N: usize;
+
+ fn f() {
+ let mut state = 0;
+ #[loop_match]
+ loop {
+ state = 'blk: {
+ match state {
+ 0 => {
+ #[const_continue]
+ break 'blk Self::N;
+ //~^ ERROR could not determine the target branch for this `#[const_continue]`
+ }
+ _ => panic!(),
+ }
+ }
+ }
+ }
+}
+
+impl T for S {
+ const N: usize = 1;
+}
+
+impl S {
+ fn h() {
+ let mut state = 0;
+ #[loop_match]
+ loop {
+ state = 'blk: {
+ match state {
+ 0 => {
+ #[const_continue]
+ break 'blk Self::N;
+ }
+ _ => panic!(),
+ }
+ }
+ }
+ }
+}
+
+trait T2<U> {
+ const L: u32;
+
+ fn p() {
+ let mut state = 0;
+ #[loop_match]
+ loop {
+ state = 'blk: {
+ match state {
+ 0 => {
+ #[const_continue]
+ break 'blk Self::L;
+ //~^ ERROR could not determine the target branch for this `#[const_continue]`
+ }
+ _ => panic!(),
+ }
+ }
+ }
+ }
+}
+
+const SIZE_OF<T>: usize = size_of::<T>();
+
+fn q<T>() {
+ let mut state = 0;
+ #[loop_match]
+ loop {
+ state = 'blk: {
+ match state {
+ 0 => {
+ #[const_continue]
+ break 'blk SIZE_OF::<T>;
+ //~^ ERROR could not determine the target branch for this `#[const_continue]`
+ }
+ _ => panic!(),
+ }
+ }
+ }
+}
+
+trait Trait<T> {
+ const X: usize = 9000;
+ const Y: usize = size_of::<T>();
+}
+
+impl<T> Trait<T> for () {}
+
+fn r<T>() {
+ let mut state = 0;
+ #[loop_match]
+ loop {
+ state = 'blk: {
+ match state {
+ 0 => {
+ #[const_continue]
+ break 'blk <() as Trait<T>>::X;
+ }
+ 1 => {
+ #[const_continue]
+ break 'blk <() as Trait<T>>::Y;
+ //~^ ERROR could not determine the target branch for this `#[const_continue]`
+ }
+ _ => panic!(),
+ }
+ }
+ }
+}
diff --git a/tests/ui/loop-match/suggest-const-item.stderr b/tests/ui/loop-match/suggest-const-item.stderr
new file mode 100644
index 0000000..7874744
--- /dev/null
+++ b/tests/ui/loop-match/suggest-const-item.stderr
@@ -0,0 +1,58 @@
+error: could not determine the target branch for this `#[const_continue]`
+ --> $DIR/suggest-const-item.rs:19:32
+ |
+LL | break 'blk const_fn();
+ | ^^^^^^^^^^ this value must be a literal or a monomorphic const
+ |
+ = help: try extracting the expression into a `const` item
+
+error: could not determine the target branch for this `#[const_continue]`
+ --> $DIR/suggest-const-item.rs:24:32
+ |
+LL | break 'blk const { const_fn() };
+ | ^^^^^^^^^^^^^^^^^^^^ `const` blocks may use generics, and are not evaluated early enough
+ |
+ = help: try extracting the expression into a `const` item
+
+error: could not determine the target branch for this `#[const_continue]`
+ --> $DIR/suggest-const-item.rs:29:32
+ |
+LL | break 'blk N;
+ | ^ constant parameters may use generics, and are not evaluated early enough
+ |
+ = help: try extracting the expression into a `const` item
+
+error: could not determine the target branch for this `#[const_continue]`
+ --> $DIR/suggest-const-item.rs:34:32
+ |
+LL | break 'blk 1 + 1;
+ | ^^^^^ this value must be a literal or a monomorphic const
+ |
+ = help: try extracting the expression into a `const` item
+
+error: could not determine the target branch for this `#[const_continue]`
+ --> $DIR/suggest-const-item.rs:76:36
+ |
+LL | break 'blk Self::N;
+ | ^^^^^^^ this value is too generic
+
+error: could not determine the target branch for this `#[const_continue]`
+ --> $DIR/suggest-const-item.rs:119:36
+ |
+LL | break 'blk Self::L;
+ | ^^^^^^^ this value is too generic
+
+error: could not determine the target branch for this `#[const_continue]`
+ --> $DIR/suggest-const-item.rs:139:32
+ |
+LL | break 'blk SIZE_OF::<T>;
+ | ^^^^^^^^^^^^ this value is too generic
+
+error: could not determine the target branch for this `#[const_continue]`
+ --> $DIR/suggest-const-item.rs:167:32
+ |
+LL | break 'blk <() as Trait<T>>::Y;
+ | ^^^^^^^^^^^^^^^^^^^ this value is too generic
+
+error: aborting due to 8 previous errors
+
diff --git a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr
index a2c281d..795d994 100644
--- a/tests/ui/macros/expr_2021_cargo_fix_edition.stderr
+++ b/tests/ui/macros/expr_2021_cargo_fix_edition.stderr
@@ -5,7 +5,7 @@
| ^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see Migration Guide <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html>
+ = note: for more information, see Migration Guide <https://doc.rust-lang.org/edition-guide/rust-2024/macro-fragment-specifiers.html>
note: the lint level is defined here
--> $DIR/expr_2021_cargo_fix_edition.rs:4:9
|
@@ -23,7 +23,7 @@
| ^^^^
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see Migration Guide <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/macro-fragment-specifiers.html>
+ = note: for more information, see Migration Guide <https://doc.rust-lang.org/edition-guide/rust-2024/macro-fragment-specifiers.html>
help: to keep the existing behavior, use the `expr_2021` fragment specifier
|
LL | ($($i:expr_2021)*) => { };
diff --git a/tests/ui/macros/macro-or-patterns-back-compat.stderr b/tests/ui/macros/macro-or-patterns-back-compat.stderr
index e04dfef..67794f0 100644
--- a/tests/ui/macros/macro-or-patterns-back-compat.stderr
+++ b/tests/ui/macros/macro-or-patterns-back-compat.stderr
@@ -5,7 +5,7 @@
| ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html>
note: the lint level is defined here
--> $DIR/macro-or-patterns-back-compat.rs:4:9
|
@@ -19,7 +19,7 @@
| ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html>
error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
--> $DIR/macro-or-patterns-back-compat.rs:19:21
@@ -28,7 +28,7 @@
| ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html>
error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
--> $DIR/macro-or-patterns-back-compat.rs:23:26
@@ -37,7 +37,7 @@
| ^^^^^^^^ help: use pat_param to preserve semantics: `$pat:pat_param`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html>
error: aborting due to 4 previous errors
diff --git a/tests/ui/macros/non-fmt-panic.stderr b/tests/ui/macros/non-fmt-panic.stderr
index 30b63cb..83410d3 100644
--- a/tests/ui/macros/non-fmt-panic.stderr
+++ b/tests/ui/macros/non-fmt-panic.stderr
@@ -74,7 +74,7 @@
| ^
|
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | assert!(false, "{}", S);
@@ -87,7 +87,7 @@
| ^^^
|
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | assert!(false, "{}", 123);
@@ -100,7 +100,7 @@
| ^^^^^^^^^
|
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{:?}" format string to use the `Debug` implementation of `Option<i32>`
|
LL | assert!(false, "{:?}", Some(123));
@@ -125,7 +125,7 @@
| ^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | panic!("{}", C);
@@ -138,7 +138,7 @@
| ^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | panic!("{}", S);
@@ -151,7 +151,7 @@
| ^
|
= note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | unreachable!("{}", S);
@@ -164,7 +164,7 @@
| ^
|
= note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | unreachable!("{}", S);
@@ -177,7 +177,7 @@
| ^^^
|
= note: this usage of `std::panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | std::panic!("{}", 123);
@@ -195,7 +195,7 @@
| ^^^^^^^
|
= note: this usage of `core::panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | core::panic!("{}", &*"abc");
@@ -208,7 +208,7 @@
| ^^^^^^^^^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{:?}" format string to use the `Debug` implementation of `Option<i32>`
|
LL | panic!("{:?}", Some(123));
@@ -262,7 +262,7 @@
| ^^^^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | panic!("{}", a!());
@@ -280,7 +280,7 @@
| ^^^^
|
= note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | unreachable!("{}", a!());
@@ -293,7 +293,7 @@
| ^^^^^^^^^^^^^^^^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
= note: the `panic!()` macro supports formatting, so there's no need for the `format!()` macro here
help: remove the `format!(..)` macro call
|
@@ -308,7 +308,7 @@
| ^^^^^^^^^^^^^^^^
|
= note: this usage of `unreachable!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
= note: the `unreachable!()` macro supports formatting, so there's no need for the `format!()` macro here
help: remove the `format!(..)` macro call
|
@@ -323,7 +323,7 @@
| ^^^^^^^^^^^^^^^^
|
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
= note: the `assert!()` macro supports formatting, so there's no need for the `format!()` macro here
help: remove the `format!(..)` macro call
|
@@ -338,7 +338,7 @@
| ^^^^^^^^^^^^^^^^
|
= note: this usage of `debug_assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
= note: the `debug_assert!()` macro supports formatting, so there's no need for the `format!()` macro here
help: remove the `format!(..)` macro call
|
@@ -353,7 +353,7 @@
| ^^^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | panic!["{}", 123];
@@ -371,7 +371,7 @@
| ^^^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | panic!{"{}", 123};
@@ -391,7 +391,7 @@
| help: use std::panic::panic_any instead: `std::panic::panic_any`
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
warning: panic message is not a string literal
--> $DIR/non-fmt-panic.rs:79:20
@@ -400,7 +400,7 @@
| ^
|
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
warning: panic message is not a string literal
--> $DIR/non-fmt-panic.rs:83:12
@@ -409,7 +409,7 @@
| ^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{:?}" format string to use the `Debug` implementation of `T`
|
LL | panic!("{:?}", v);
@@ -427,7 +427,7 @@
| ^
|
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{:?}" format string to use the `Debug` implementation of `T`
|
LL | assert!(false, "{:?}", v);
@@ -440,7 +440,7 @@
| ^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | panic!("{}", v);
@@ -458,7 +458,7 @@
| ^
|
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | assert!(false, "{}", v);
@@ -471,7 +471,7 @@
| ^
|
= note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | panic!("{}", v);
@@ -489,7 +489,7 @@
| ^
|
= note: this usage of `assert!()` is deprecated; it will be a hard error in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/panic-macro-consistency.html>
help: add a "{}" format string to `Display` the message
|
LL | assert!(false, "{}", v);
diff --git a/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr b/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
index 523134a..51d0f85 100644
--- a/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
+++ b/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
@@ -2,9 +2,11 @@
--> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:9:28
|
LL | let i = Box::new(3);
- | - captured outer variable
+ | - ----------- move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | let _f = to_fn(|| test(i));
- | -- ^ move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
+ | -- ^ `i` is moved here
| |
| captured by this `Fn` closure
|
diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr
index 6de323a..b7df6fb 100644
--- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr
+++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail
--> $DIR/defaulted-never-note.rs:32:9
@@ -28,7 +28,7 @@
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will fail
--> $DIR/defaulted-never-note.rs:32:9
diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
index be80756..6ee57d5 100644
--- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
+++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/dependency-on-fallback-to-unit.rs:12:19
@@ -26,7 +26,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/dependency-on-fallback-to-unit.rs:22:5
@@ -48,7 +48,7 @@
| ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/dependency-on-fallback-to-unit.rs:12:19
@@ -70,7 +70,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/dependency-on-fallback-to-unit.rs:22:5
diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
index 44ebdb4..64a8ecd 100644
--- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: UnitDefault` will fail
--> $DIR/diverging-fallback-control-flow.rs:36:13
@@ -25,7 +25,7 @@
| ^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: UnitDefault` will fail
--> $DIR/diverging-fallback-control-flow.rs:50:13
@@ -47,7 +47,7 @@
| ^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: UnitDefault` will fail
--> $DIR/diverging-fallback-control-flow.rs:36:13
@@ -68,7 +68,7 @@
| ^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: UnitDefault` will fail
--> $DIR/diverging-fallback-control-flow.rs:50:13
diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
index 4a8dea4..ec48c38 100644
--- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Test` will fail
--> $DIR/diverging-fallback-no-leak.rs:20:23
@@ -28,7 +28,7 @@
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Test` will fail
--> $DIR/diverging-fallback-no-leak.rs:20:23
diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
index 803af39..48debdd 100644
--- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: UnitReturn` will fail
--> $DIR/diverging-fallback-unconstrained-return.rs:39:23
@@ -28,7 +28,7 @@
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: UnitReturn` will fail
--> $DIR/diverging-fallback-unconstrained-return.rs:39:23
diff --git a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr
index 365e886..d2d108e 100644
--- a/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr
+++ b/tests/ui/never_type/dont-suggest-turbofish-from-expansion.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/dont-suggest-turbofish-from-expansion.rs:14:23
@@ -32,7 +32,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/dont-suggest-turbofish-from-expansion.rs:14:23
diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
index cf19363..5651a26 100644
--- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
+++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Bar` will fail
--> $DIR/fallback-closure-ret.rs:24:5
@@ -28,7 +28,7 @@
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Bar` will fail
--> $DIR/fallback-closure-ret.rs:24:5
diff --git a/tests/ui/never_type/impl_trait_fallback.stderr b/tests/ui/never_type/impl_trait_fallback.stderr
index 7250db1..36d2eae 100644
--- a/tests/ui/never_type/impl_trait_fallback.stderr
+++ b/tests/ui/never_type/impl_trait_fallback.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: T` will fail
--> $DIR/impl_trait_fallback.rs:8:25
@@ -24,7 +24,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: T` will fail
--> $DIR/impl_trait_fallback.rs:8:25
diff --git a/tests/ui/never_type/lint-breaking-2024-assign-underscore.stderr b/tests/ui/never_type/lint-breaking-2024-assign-underscore.stderr
index 945db40..6a85b99 100644
--- a/tests/ui/never_type/lint-breaking-2024-assign-underscore.stderr
+++ b/tests/ui/never_type/lint-breaking-2024-assign-underscore.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/lint-breaking-2024-assign-underscore.rs:13:9
@@ -32,7 +32,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the types explicitly
note: in edition 2024, the requirement `!: Default` will fail
--> $DIR/lint-breaking-2024-assign-underscore.rs:13:9
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
index c90efd2..48734f3 100644
--- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -20,7 +20,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -34,7 +34,7 @@
| ^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
warning: never type fallback affects this raw pointer dereference
@@ -44,7 +44,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -58,7 +58,7 @@
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -72,7 +72,7 @@
| ^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -86,7 +86,7 @@
| ^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -100,7 +100,7 @@
| ^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -114,7 +114,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
warning: never type fallback affects this call to an `unsafe` function
@@ -127,7 +127,7 @@
| ----------- in this macro invocation
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -141,7 +141,7 @@
| ^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -157,7 +157,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -173,7 +173,7 @@
| ^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
@@ -185,7 +185,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -201,7 +201,7 @@
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -217,7 +217,7 @@
| ^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -233,7 +233,7 @@
| ^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -249,7 +249,7 @@
| ^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -265,7 +265,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
@@ -280,7 +280,7 @@
| ----------- in this macro invocation
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
= note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
index 858d738..8039ef4 100644
--- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -20,7 +20,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -34,7 +34,7 @@
| ^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
error: never type fallback affects this raw pointer dereference
@@ -44,7 +44,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -58,7 +58,7 @@
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -72,7 +72,7 @@
| ^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -86,7 +86,7 @@
| ^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -100,7 +100,7 @@
| ^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
help: use `()` annotations to avoid fallback changes
|
@@ -114,7 +114,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
error: never type fallback affects this call to an `unsafe` function
@@ -127,7 +127,7 @@
| ----------- in this macro invocation
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -150,7 +150,7 @@
| ^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -166,7 +166,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -182,7 +182,7 @@
| ^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
@@ -194,7 +194,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -210,7 +210,7 @@
| ^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -226,7 +226,7 @@
| ^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -242,7 +242,7 @@
| ^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -258,7 +258,7 @@
| ^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
help: use `()` annotations to avoid fallback changes
@@ -274,7 +274,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
@@ -289,7 +289,7 @@
| ----------- in this macro invocation
|
= warning: this changes meaning in Rust 2024 and in a future release in all editions!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/never-type-fallback.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>
= help: specify the type explicitly
= note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
= note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
index 8268f5d..331c651 100644
--- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
+++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
@@ -4,7 +4,7 @@
LL | S1 { a: unsafe { &mut X1 } }
| ^^^^^^^ mutable reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw mut` instead to create a raw pointer
diff --git a/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr b/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr
index fbaec8a..5754603 100644
--- a/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr
+++ b/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr
@@ -2,9 +2,11 @@
--> $DIR/issue-52663-span-decl-captured-variable.rs:8:26
|
LL | let x = (vec![22], vec![44]);
- | - captured outer variable
+ | - -------------------- move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | expect_fn(|| drop(x.0));
- | -- ^^^ move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
+ | -- ^^^ `x.0` is moved here
| |
| captured by this `Fn` closure
|
diff --git a/tests/ui/parser/recover/recover-pat-ranges.stderr b/tests/ui/parser/recover/recover-pat-ranges.stderr
index 6c17182..246c704 100644
--- a/tests/ui/parser/recover/recover-pat-ranges.stderr
+++ b/tests/ui/parser/recover/recover-pat-ranges.stderr
@@ -191,7 +191,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
error: aborting due to 13 previous errors; 1 warning emitted
diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr
index a2f3ba4..1570475 100644
--- a/tests/ui/parser/recover/recover-range-pats.stderr
+++ b/tests/ui/parser/recover/recover-range-pats.stderr
@@ -339,7 +339,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/recover-range-pats.rs:6:9
|
@@ -353,7 +353,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
error: `...` range patterns are deprecated
--> $DIR/recover-range-pats.rs:46:13
@@ -362,7 +362,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
error: `...` range patterns are deprecated
--> $DIR/recover-range-pats.rs:49:13
@@ -371,7 +371,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
error: `...` range patterns are deprecated
--> $DIR/recover-range-pats.rs:52:16
@@ -380,7 +380,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
error: `...` range patterns are deprecated
--> $DIR/recover-range-pats.rs:55:13
@@ -389,7 +389,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
error: `...` range patterns are deprecated
--> $DIR/recover-range-pats.rs:58:14
@@ -398,7 +398,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
error: `...` range patterns are deprecated
--> $DIR/recover-range-pats.rs:62:13
@@ -407,7 +407,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
error: `...` range patterns are deprecated
--> $DIR/recover-range-pats.rs:137:20
@@ -419,7 +419,7 @@
| ----------- in this macro invocation
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0029]: only `char` and numeric types are allowed in range patterns
diff --git a/tests/ui/parser/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr
index 26d388f..b206754 100644
--- a/tests/ui/parser/trait-object-trait-parens.stderr
+++ b/tests/ui/parser/trait-object-trait-parens.stderr
@@ -23,7 +23,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -48,7 +48,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
@@ -72,7 +72,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
diff --git a/tests/ui/privacy/associated-item-privacy-trait.stderr b/tests/ui/privacy/associated-item-privacy-trait.stderr
index f79c4cf..4e9dfa4a 100644
--- a/tests/ui/privacy/associated-item-privacy-trait.stderr
+++ b/tests/ui/privacy/associated-item-privacy-trait.stderr
@@ -75,6 +75,17 @@
|
= note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+error: trait `PrivTr` is private
+ --> $DIR/associated-item-privacy-trait.rs:29:14
+ |
+LL | impl PrivTr for u8 {}
+ | ^^^^^^ private trait
+...
+LL | priv_trait::mac!();
+ | ------------------ in this macro invocation
+ |
+ = note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
error: type `priv_signature::Priv` is private
--> $DIR/associated-item-privacy-trait.rs:46:21
|
@@ -317,16 +328,5 @@
|
= note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
-error: trait `PrivTr` is private
- --> $DIR/associated-item-privacy-trait.rs:29:14
- |
-LL | impl PrivTr for u8 {}
- | ^^^^^^ private trait
-...
-LL | priv_trait::mac!();
- | ------------------ in this macro invocation
- |
- = note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
-
error: aborting due to 30 previous errors
diff --git a/tests/ui/privacy/private-in-public-warn.stderr b/tests/ui/privacy/private-in-public-warn.stderr
index c2a57e3..86f6be8 100644
--- a/tests/ui/privacy/private-in-public-warn.stderr
+++ b/tests/ui/privacy/private-in-public-warn.stderr
@@ -84,42 +84,6 @@
LL | struct Priv;
| ^^^^^^^^^^^
-error: type `types::Priv` is more private than the item `types::ES`
- --> $DIR/private-in-public-warn.rs:27:9
- |
-LL | pub static ES: Priv;
- | ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
- |
-note: but type `types::Priv` is only usable at visibility `pub(self)`
- --> $DIR/private-in-public-warn.rs:9:5
- |
-LL | struct Priv;
- | ^^^^^^^^^^^
-
-error: type `types::Priv` is more private than the item `types::ef1`
- --> $DIR/private-in-public-warn.rs:28:9
- |
-LL | pub fn ef1(arg: Priv);
- | ^^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
- |
-note: but type `types::Priv` is only usable at visibility `pub(self)`
- --> $DIR/private-in-public-warn.rs:9:5
- |
-LL | struct Priv;
- | ^^^^^^^^^^^
-
-error: type `types::Priv` is more private than the item `types::ef2`
- --> $DIR/private-in-public-warn.rs:29:9
- |
-LL | pub fn ef2() -> Priv;
- | ^^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
- |
-note: but type `types::Priv` is only usable at visibility `pub(self)`
- --> $DIR/private-in-public-warn.rs:9:5
- |
-LL | struct Priv;
- | ^^^^^^^^^^^
-
error[E0446]: private type `types::Priv` in public interface
--> $DIR/private-in-public-warn.rs:32:9
|
@@ -395,6 +359,42 @@
LL | struct Priv2;
| ^^^^^^^^^^^^
+error: type `types::Priv` is more private than the item `types::ES`
+ --> $DIR/private-in-public-warn.rs:27:9
+ |
+LL | pub static ES: Priv;
+ | ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
+ |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+ --> $DIR/private-in-public-warn.rs:9:5
+ |
+LL | struct Priv;
+ | ^^^^^^^^^^^
+
+error: type `types::Priv` is more private than the item `types::ef1`
+ --> $DIR/private-in-public-warn.rs:28:9
+ |
+LL | pub fn ef1(arg: Priv);
+ | ^^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
+ |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+ --> $DIR/private-in-public-warn.rs:9:5
+ |
+LL | struct Priv;
+ | ^^^^^^^^^^^
+
+error: type `types::Priv` is more private than the item `types::ef2`
+ --> $DIR/private-in-public-warn.rs:29:9
+ |
+LL | pub fn ef2() -> Priv;
+ | ^^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
+ |
+note: but type `types::Priv` is only usable at visibility `pub(self)`
+ --> $DIR/private-in-public-warn.rs:9:5
+ |
+LL | struct Priv;
+ | ^^^^^^^^^^^
+
warning: bounds on generic parameters in type aliases are not enforced
--> $DIR/private-in-public-warn.rs:42:23
|
diff --git a/tests/ui/privacy/sealed-traits/false-sealed-traits-note.rs b/tests/ui/privacy/sealed-traits/false-sealed-traits-note.rs
index 13f3065..d5065a6 100644
--- a/tests/ui/privacy/sealed-traits/false-sealed-traits-note.rs
+++ b/tests/ui/privacy/sealed-traits/false-sealed-traits-note.rs
@@ -1,5 +1,6 @@
-// We should not emit sealed traits note, see issue #143392
+// We should not emit sealed traits note, see issue #143392 and #143121
+/// Reported in #143392
mod inner {
pub trait TraitA {}
@@ -10,4 +11,13 @@ pub trait TraitB: TraitA {}
impl inner::TraitB for Struct {} //~ ERROR the trait bound `Struct: TraitA` is not satisfied [E0277]
+/// Reported in #143121
+mod x {
+ pub trait A {}
+ pub trait B: A {}
+
+ pub struct C;
+ impl B for C {} //~ ERROR the trait bound `C: A` is not satisfied [E0277]
+}
+
fn main(){}
diff --git a/tests/ui/privacy/sealed-traits/false-sealed-traits-note.stderr b/tests/ui/privacy/sealed-traits/false-sealed-traits-note.stderr
index f80d985..df80165 100644
--- a/tests/ui/privacy/sealed-traits/false-sealed-traits-note.stderr
+++ b/tests/ui/privacy/sealed-traits/false-sealed-traits-note.stderr
@@ -1,20 +1,37 @@
error[E0277]: the trait bound `Struct: TraitA` is not satisfied
- --> $DIR/false-sealed-traits-note.rs:11:24
+ --> $DIR/false-sealed-traits-note.rs:12:24
|
LL | impl inner::TraitB for Struct {}
| ^^^^^^ the trait `TraitA` is not implemented for `Struct`
|
help: this trait has no implementations, consider adding one
- --> $DIR/false-sealed-traits-note.rs:4:5
+ --> $DIR/false-sealed-traits-note.rs:5:5
|
LL | pub trait TraitA {}
| ^^^^^^^^^^^^^^^^
note: required by a bound in `TraitB`
- --> $DIR/false-sealed-traits-note.rs:6:23
+ --> $DIR/false-sealed-traits-note.rs:7:23
|
LL | pub trait TraitB: TraitA {}
| ^^^^^^ required by this bound in `TraitB`
-error: aborting due to 1 previous error
+error[E0277]: the trait bound `C: A` is not satisfied
+ --> $DIR/false-sealed-traits-note.rs:20:16
+ |
+LL | impl B for C {}
+ | ^ the trait `A` is not implemented for `C`
+ |
+help: this trait has no implementations, consider adding one
+ --> $DIR/false-sealed-traits-note.rs:16:5
+ |
+LL | pub trait A {}
+ | ^^^^^^^^^^^
+note: required by a bound in `B`
+ --> $DIR/false-sealed-traits-note.rs:17:18
+ |
+LL | pub trait B: A {}
+ | ^ required by this bound in `B`
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/range/range-inclusive-pattern-precedence.stderr b/tests/ui/range/range-inclusive-pattern-precedence.stderr
index 9df20fc..15237b0 100644
--- a/tests/ui/range/range-inclusive-pattern-precedence.stderr
+++ b/tests/ui/range/range-inclusive-pattern-precedence.stderr
@@ -16,7 +16,7 @@
| ^^^^^^ help: use `..=` for an inclusive range: `&(0..=9)`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/range-inclusive-pattern-precedence.rs:7:9
|
diff --git a/tests/ui/range/range-inclusive-pattern-precedence2.stderr b/tests/ui/range/range-inclusive-pattern-precedence2.stderr
index fd2fa78..4c5016b 100644
--- a/tests/ui/range/range-inclusive-pattern-precedence2.stderr
+++ b/tests/ui/range/range-inclusive-pattern-precedence2.stderr
@@ -16,7 +16,7 @@
| ^^^ help: use `..=` for an inclusive range
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/range-inclusive-pattern-precedence2.rs:5:9
|
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr
index ea46260..e16841b 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.stderr
@@ -79,7 +79,7 @@
LL | sse2();
| ^^^^^^ call to function with `#[target_feature]`
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= help: in order for the call to be safe, the context requires the following additional target feature: sse2
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
note: an unsafe function restricts its caller, but its body is safe by default
diff --git a/tests/ui/runtime/backtrace-debuginfo.rs b/tests/ui/runtime/backtrace-debuginfo.rs
index 37fce27..5fb9943 100644
--- a/tests/ui/runtime/backtrace-debuginfo.rs
+++ b/tests/ui/runtime/backtrace-debuginfo.rs
@@ -43,12 +43,13 @@ macro_rules! dump_and_die {
// rust-lang/rust to test it as well, but sometimes we just gotta keep
// landing PRs.
//
- // aarch64-msvc is broken as its backtraces are truncated.
+ // aarch64-msvc/arm64ec-msvc is broken as its backtraces are truncated.
// See https://github.com/rust-lang/rust/issues/140489
if cfg!(any(target_os = "android",
all(target_os = "linux", target_arch = "arm"),
all(target_env = "msvc", target_arch = "x86"),
all(target_env = "msvc", target_arch = "aarch64"),
+ all(target_env = "msvc", target_arch = "arm64ec"),
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd")) {
diff --git a/tests/ui/rust-2021/array-into-iter-ambiguous.stderr b/tests/ui/rust-2021/array-into-iter-ambiguous.stderr
index 2a724bd..6e510df 100644
--- a/tests/ui/rust-2021/array-into-iter-ambiguous.stderr
+++ b/tests/ui/rust-2021/array-into-iter-ambiguous.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)`
|
= warning: this changes meaning in Rust 2021
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/IntoIterator-for-arrays.html>
note: the lint level is defined here
--> $DIR/array-into-iter-ambiguous.rs:5:9
|
diff --git a/tests/ui/rust-2021/future-prelude-collision-generic-trait.stderr b/tests/ui/rust-2021/future-prelude-collision-generic-trait.stderr
index f38da13..bbc85d5 100644
--- a/tests/ui/rust-2021/future-prelude-collision-generic-trait.stderr
+++ b/tests/ui/rust-2021/future-prelude-collision-generic-trait.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^ help: disambiguate the associated function: `<U as PyTryFrom<'_, _>>::try_from`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
note: the lint level is defined here
--> $DIR/future-prelude-collision-generic-trait.rs:5:9
|
diff --git a/tests/ui/rust-2021/future-prelude-collision-generic.stderr b/tests/ui/rust-2021/future-prelude-collision-generic.stderr
index 9893b3e..06ee6b4 100644
--- a/tests/ui/rust-2021/future-prelude-collision-generic.stderr
+++ b/tests/ui/rust-2021/future-prelude-collision-generic.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<'_, _> as MyFromIter>::from_iter`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
note: the lint level is defined here
--> $DIR/future-prelude-collision-generic.rs:5:9
|
@@ -19,7 +19,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<'static, i32> as MyFromIter>::from_iter`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision-generic.rs:34:5
@@ -28,7 +28,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<'_, _> as MyFromIter>::from_iter`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: 3 warnings emitted
diff --git a/tests/ui/rust-2021/future-prelude-collision-imported.stderr b/tests/ui/rust-2021/future-prelude-collision-imported.stderr
index c1d72d0..8f650e9 100644
--- a/tests/ui/rust-2021/future-prelude-collision-imported.stderr
+++ b/tests/ui/rust-2021/future-prelude-collision-imported.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
note: the lint level is defined here
--> $DIR/future-prelude-collision-imported.rs:4:9
|
@@ -19,7 +19,7 @@
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `crate::m::TryIntoU32::try_into(3u8)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait method `try_into` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision-imported.rs:53:22
@@ -28,7 +28,7 @@
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `super::m::TryIntoU32::try_into(3u8)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait method `try_into` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision-imported.rs:64:22
@@ -37,7 +37,7 @@
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: 4 warnings emitted
diff --git a/tests/ui/rust-2021/future-prelude-collision-macros.stderr b/tests/ui/rust-2021/future-prelude-collision-macros.stderr
index 4d4a076..c2d8c85 100644
--- a/tests/ui/rust-2021/future-prelude-collision-macros.stderr
+++ b/tests/ui/rust-2021/future-prelude-collision-macros.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyTry::try_into(foo!(), todo!())`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
note: the lint level is defined here
--> $DIR/future-prelude-collision-macros.rs:4:9
|
@@ -19,7 +19,7 @@
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<bar!() as TryFromU8>::try_from`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: 2 warnings emitted
diff --git a/tests/ui/rust-2021/future-prelude-collision-turbofish.stderr b/tests/ui/rust-2021/future-prelude-collision-turbofish.stderr
index c0ef80f..73ed238 100644
--- a/tests/ui/rust-2021/future-prelude-collision-turbofish.stderr
+++ b/tests/ui/rust-2021/future-prelude-collision-turbofish.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `AnnotatableTryInto::try_into::<usize>(x)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
note: the lint level is defined here
--> $DIR/future-prelude-collision-turbofish.rs:6:9
|
@@ -19,7 +19,7 @@
| ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `AnnotatableTryInto::try_into::<usize>(x)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: 2 warnings emitted
diff --git a/tests/ui/rust-2021/future-prelude-collision.stderr b/tests/ui/rust-2021/future-prelude-collision.stderr
index cae113f..0b25145 100644
--- a/tests/ui/rust-2021/future-prelude-collision.stderr
+++ b/tests/ui/rust-2021/future-prelude-collision.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
note: the lint level is defined here
--> $DIR/future-prelude-collision.rs:4:9
|
@@ -19,7 +19,7 @@
| ^^^^^^^^^^^^^ help: disambiguate the associated function: `<u32 as TryFromU8>::try_from`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision.rs:66:13
@@ -28,7 +28,7 @@
| ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<u8> as FromByteIterator>::from_iter`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait-associated function `try_from` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision.rs:74:18
@@ -37,7 +37,7 @@
| ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait method `try_into` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision.rs:79:18
@@ -46,7 +46,7 @@
| ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait method `try_into` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision.rs:84:18
@@ -55,7 +55,7 @@
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait method `try_into` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision.rs:90:18
@@ -64,7 +64,7 @@
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: trait-associated function `try_from` will become ambiguous in Rust 2021
--> $DIR/future-prelude-collision.rs:95:13
@@ -73,7 +73,7 @@
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<U32Alias as TryFromU8>::try_from`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
warning: 8 warnings emitted
diff --git a/tests/ui/rust-2021/generic-type-collision.stderr b/tests/ui/rust-2021/generic-type-collision.stderr
index 1ec6104..c2d2968 100644
--- a/tests/ui/rust-2021/generic-type-collision.stderr
+++ b/tests/ui/rust-2021/generic-type-collision.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<i32> as MyTrait<_>>::from_iter`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
note: the lint level is defined here
--> $DIR/generic-type-collision.rs:4:9
|
diff --git a/tests/ui/rust-2021/inherent-dyn-collision.stderr b/tests/ui/rust-2021/inherent-dyn-collision.stderr
index d9e720d..d582e4a 100644
--- a/tests/ui/rust-2021/inherent-dyn-collision.stderr
+++ b/tests/ui/rust-2021/inherent-dyn-collision.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^ help: disambiguate the method call: `(&*get_dyn_trait())`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>
note: the lint level is defined here
--> $DIR/inherent-dyn-collision.rs:8:9
|
diff --git a/tests/ui/rust-2021/reserved-prefixes-migration.stderr b/tests/ui/rust-2021/reserved-prefixes-migration.stderr
index 20914d1..8092c63 100644
--- a/tests/ui/rust-2021/reserved-prefixes-migration.stderr
+++ b/tests/ui/rust-2021/reserved-prefixes-migration.stderr
@@ -5,7 +5,7 @@
| ^ unknown prefix
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html>
note: the lint level is defined here
--> $DIR/reserved-prefixes-migration.rs:5:9
|
@@ -23,7 +23,7 @@
| ^^^^^^ unknown prefix
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
LL | m2!(prefix "hey");
@@ -36,7 +36,7 @@
| ^^^ unknown prefix
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
LL | m3!(hey #123);
@@ -49,7 +49,7 @@
| ^^^ unknown prefix
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
LL | m3!(hey #hey);
@@ -62,7 +62,7 @@
| ^^^^ unknown prefix
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html>
help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021
|
LL | #name = #kind #value
diff --git a/tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr b/tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr
index 0735be2..6da2cb97 100644
--- a/tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr
+++ b/tests/ui/rust-2024/box-slice-into-iter-ambiguous.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)`
|
= warning: this changes meaning in Rust 2024
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/intoiterator-box-slice.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html>
note: the lint level is defined here
--> $DIR/box-slice-into-iter-ambiguous.rs:5:9
|
diff --git a/tests/ui/rust-2024/gen-kw.e2015.stderr b/tests/ui/rust-2024/gen-kw.e2015.stderr
index 3fca7b4..ebb80cf 100644
--- a/tests/ui/rust-2024/gen-kw.e2015.stderr
+++ b/tests/ui/rust-2024/gen-kw.e2015.stderr
@@ -5,7 +5,7 @@
| ^^^ help: you can use a raw identifier to stay compatible: `r#gen`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
note: the lint level is defined here
--> $DIR/gen-kw.rs:4:9
|
@@ -20,7 +20,7 @@
| ^^^ help: you can use a raw identifier to stay compatible: `r#gen`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:19:27
@@ -29,7 +29,7 @@
| ^^^ help: you can use a raw identifier to stay compatible: `r#gen`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:25:9
@@ -38,7 +38,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:25:19
@@ -47,7 +47,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:33:13
@@ -56,7 +56,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:33:28
@@ -65,7 +65,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:33:37
@@ -74,7 +74,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: aborting due to 8 previous errors
diff --git a/tests/ui/rust-2024/gen-kw.e2018.stderr b/tests/ui/rust-2024/gen-kw.e2018.stderr
index b7f2c88..e491454 100644
--- a/tests/ui/rust-2024/gen-kw.e2018.stderr
+++ b/tests/ui/rust-2024/gen-kw.e2018.stderr
@@ -5,7 +5,7 @@
| ^^^ help: you can use a raw identifier to stay compatible: `r#gen`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
note: the lint level is defined here
--> $DIR/gen-kw.rs:4:9
|
@@ -20,7 +20,7 @@
| ^^^ help: you can use a raw identifier to stay compatible: `r#gen`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:19:27
@@ -29,7 +29,7 @@
| ^^^ help: you can use a raw identifier to stay compatible: `r#gen`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:25:9
@@ -38,7 +38,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:25:19
@@ -47,7 +47,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:33:13
@@ -56,7 +56,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:33:28
@@ -65,7 +65,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: `gen` is a keyword in the 2024 edition
--> $DIR/gen-kw.rs:33:37
@@ -74,7 +74,7 @@
| ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/gen-keyword.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html>
error: aborting due to 8 previous errors
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr
index 15a3fa1..8e5c3f4 100644
--- a/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-async-block.e2021.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())`
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html>
note: the lint level is defined here
--> $DIR/future-poll-async-block.rs:7:9
|
diff --git a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr
index 633731c..7076952 100644
--- a/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr
+++ b/tests/ui/rust-2024/prelude-migration/future-poll-not-future-pinned.e2021.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(()))`
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html>
note: the lint level is defined here
--> $DIR/future-poll-not-future-pinned.rs:7:9
|
diff --git a/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr
index 5865029..2e88751 100644
--- a/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr
+++ b/tests/ui/rust-2024/prelude-migration/in_2024_compatibility.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::poll(&core::pin::pin!(async {}), &mut context())`
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html>
note: the lint level is defined here
--> $DIR/in_2024_compatibility.rs:3:9
|
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr
index e67f07b..690c58f 100644
--- a/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr
+++ b/tests/ui/rust-2024/prelude-migration/into-future-adt.e2021.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)`
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html>
note: the lint level is defined here
--> $DIR/into-future-adt.rs:7:9
|
diff --git a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr
index 0588f5b..4423e12 100644
--- a/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr
+++ b/tests/ui/rust-2024/prelude-migration/into-future-not-into-future.e2021.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `Meow::into_future(&Cat)`
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/prelude.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html>
note: the lint level is defined here
--> $DIR/into-future-not-into-future.rs:7:9
|
diff --git a/tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr b/tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr
index bf74f6e..488f66b 100644
--- a/tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr
+++ b/tests/ui/rust-2024/reserved-guarded-strings-lexing.stderr
@@ -35,7 +35,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
note: the lint level is defined here
--> $DIR/reserved-guarded-strings-lexing.rs:4:9
|
@@ -53,7 +53,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!(# ## "foo");
@@ -66,7 +66,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!(## # "foo");
@@ -79,7 +79,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!(# # "foo"#);
@@ -92,7 +92,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo7!(# ## "foo"###);
@@ -105,7 +105,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo7!(## # "foo"###);
@@ -118,7 +118,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo7!(### "foo"# ##);
@@ -131,7 +131,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo7!(### "foo"## #);
@@ -144,7 +144,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo5!(# ##"foo"#);
@@ -157,7 +157,7 @@
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo5!(## #"foo"#);
@@ -170,7 +170,7 @@
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo5!(### "foo"#);
@@ -183,7 +183,7 @@
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo5!(# "foo"###);
@@ -196,7 +196,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo5!(#"foo"# ##);
@@ -209,7 +209,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo5!(#"foo"## #);
@@ -222,7 +222,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!("foo"# ##);
@@ -235,7 +235,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!("foo"## #);
@@ -248,7 +248,7 @@
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo4!(Ñ# ""#);
@@ -261,7 +261,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo3!(🙃# "");
diff --git a/tests/ui/rust-2024/reserved-guarded-strings-migration.stderr b/tests/ui/rust-2024/reserved-guarded-strings-migration.stderr
index 59f920c..9e6c455 100644
--- a/tests/ui/rust-2024/reserved-guarded-strings-migration.stderr
+++ b/tests/ui/rust-2024/reserved-guarded-strings-migration.stderr
@@ -5,7 +5,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
note: the lint level is defined here
--> $DIR/reserved-guarded-strings-migration.rs:5:9
|
@@ -23,7 +23,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!(# ## "foo");
@@ -36,7 +36,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!(## # "foo");
@@ -49,7 +49,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!(# # "foo"#);
@@ -62,7 +62,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo6!(# ## "foo"##);
@@ -75,7 +75,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo6!(## # "foo"##);
@@ -88,7 +88,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo6!(### "foo"# #);
@@ -101,7 +101,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!("foo"# ##);
@@ -114,7 +114,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo4!("foo"## #);
@@ -127,7 +127,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo2!(# "");
@@ -140,7 +140,7 @@
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo3!(# ""#);
@@ -153,7 +153,7 @@
| ^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo3!(# #"");
@@ -166,7 +166,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo3!(## "");
@@ -179,7 +179,7 @@
| ^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo2!(# "foo");
@@ -192,7 +192,7 @@
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo3!(# #"foo");
@@ -205,7 +205,7 @@
| ^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo3!(## "foo");
@@ -218,7 +218,7 @@
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo3!(# "foo"#);
@@ -231,7 +231,7 @@
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo4!(# #"foo"#);
@@ -244,7 +244,7 @@
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo4!(## "foo"#);
@@ -257,7 +257,7 @@
| ^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo5!(# #"foo"##);
@@ -270,7 +270,7 @@
| ^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a guarded string in Rust 2024
|
LL | demo5!(## "foo"##);
@@ -283,7 +283,7 @@
| ^^
|
= warning: this is accepted in the current edition (Rust 2021) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/reserved-syntax.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>
help: insert whitespace here to avoid this being parsed as a forbidden token in Rust 2024
|
LL | demo5!(##"foo"# #);
diff --git a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr
index f0a49f5..2b77f6e 100644
--- a/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr
+++ b/tests/ui/rust-2024/unsafe-attributes/in_2024_compatibility.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^ usage of unsafe attribute
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>
note: the lint level is defined here
--> $DIR/in_2024_compatibility.rs:1:9
|
diff --git a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr
index 15a48fb..b97176f 100644
--- a/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr
+++ b/tests/ui/rust-2024/unsafe-attributes/unsafe-attributes-fix.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^ usage of unsafe attribute
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>
note: the lint level is defined here
--> $DIR/unsafe-attributes-fix.rs:2:9
|
@@ -26,7 +26,7 @@
| ----------------- in this macro invocation
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>
= note: this error originates in the macro `ident` (in Nightly builds, run with -Z macro-backtrace for more info)
help: wrap the attribute in `unsafe(...)`
|
@@ -40,7 +40,7 @@
| ^^^^^^^^^ usage of unsafe attribute
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>
help: wrap the attribute in `unsafe(...)`
|
LL | meta!(unsafe(no_mangle));
@@ -53,7 +53,7 @@
| ^^^^^^^^^^^ usage of unsafe attribute
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>
help: wrap the attribute in `unsafe(...)`
|
LL | meta2!(unsafe(export_name = "baw"));
@@ -69,7 +69,7 @@
| ---------------------------- in this macro invocation
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>
= note: this error originates in the macro `ident2` (in Nightly builds, run with -Z macro-backtrace for more info)
help: wrap the attribute in `unsafe(...)`
|
@@ -86,7 +86,7 @@
| ---------------- in this macro invocation
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>
= note: this error originates in the macro `with_cfg_attr` (in Nightly builds, run with -Z macro-backtrace for more info)
help: wrap the attribute in `unsafe(...)`
|
@@ -100,7 +100,7 @@
| ^^^^^^^^^ usage of unsafe attribute
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-attributes.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>
help: wrap the attribute in `unsafe(...)`
|
LL | #[unsafe(no_mangle)]
diff --git a/tests/ui/rust-2024/unsafe-env-suggestion.stderr b/tests/ui/rust-2024/unsafe-env-suggestion.stderr
index 6c95d50..3c5ceaa 100644
--- a/tests/ui/rust-2024/unsafe-env-suggestion.stderr
+++ b/tests/ui/rust-2024/unsafe-env-suggestion.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/newly-unsafe-functions.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/newly-unsafe-functions.html>
note: the lint level is defined here
--> $DIR/unsafe-env-suggestion.rs:3:9
|
@@ -24,7 +24,7 @@
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/newly-unsafe-functions.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/newly-unsafe-functions.html>
help: you can wrap the call in an `unsafe` block if you can guarantee that the environment access only happens in single-threaded code
|
LL + // TODO: Audit that the environment access only happens in single-threaded code.
diff --git a/tests/ui/rust-2024/unsafe-env.e2021.stderr b/tests/ui/rust-2024/unsafe-env.e2021.stderr
index 4a441cf..a73db9f 100644
--- a/tests/ui/rust-2024/unsafe-env.e2021.stderr
+++ b/tests/ui/rust-2024/unsafe-env.e2021.stderr
@@ -4,7 +4,7 @@
LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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:8:1
diff --git a/tests/ui/rust-2024/unsafe-env.e2024.stderr b/tests/ui/rust-2024/unsafe-env.e2024.stderr
index 0ee7e04..cb48ae2 100644
--- a/tests/ui/rust-2024/unsafe-env.e2024.stderr
+++ b/tests/ui/rust-2024/unsafe-env.e2024.stderr
@@ -4,7 +4,7 @@
LL | env::set_var("FOO", "BAR");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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:8:1
@@ -23,7 +23,7 @@
LL | env::remove_var("FOO");
| ^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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
@@ -32,7 +32,7 @@
LL | unsafe_fn();
| ^^^^^^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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
diff --git a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.stderr b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.stderr
index ab12da0..9a535fb 100644
--- a/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.stderr
+++ b/tests/ui/rust-2024/unsafe-extern-blocks/unsafe-extern-suggestion.stderr
@@ -14,7 +14,7 @@
| |_^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-extern.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-extern.html>
note: the lint level is defined here
--> $DIR/unsafe-extern-suggestion.rs:3:9
|
diff --git a/tests/ui/simd/repr-simd-on-enum.rs b/tests/ui/simd/repr-simd-on-enum.rs
new file mode 100644
index 0000000..49cf9e9
--- /dev/null
+++ b/tests/ui/simd/repr-simd-on-enum.rs
@@ -0,0 +1,15 @@
+// Used to ICE; see <https://github.com/rust-lang/rust/issues/121097>
+
+#![feature(repr_simd)]
+
+#[repr(simd)] //~ ERROR attribute should be applied to a struct
+enum Aligned {
+ Zero = 0,
+ One = 1,
+}
+
+fn tou8(al: Aligned) -> u8 {
+ al as u8
+}
+
+fn main() {}
diff --git a/tests/ui/simd/repr-simd-on-enum.stderr b/tests/ui/simd/repr-simd-on-enum.stderr
new file mode 100644
index 0000000..6a19a16
--- /dev/null
+++ b/tests/ui/simd/repr-simd-on-enum.stderr
@@ -0,0 +1,14 @@
+error[E0517]: attribute should be applied to a struct
+ --> $DIR/repr-simd-on-enum.rs:5:8
+ |
+LL | #[repr(simd)]
+ | ^^^^
+LL | / enum Aligned {
+LL | | Zero = 0,
+LL | | One = 1,
+LL | | }
+ | |_- not a struct
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0517`.
diff --git a/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr b/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr
index 8ead943..f656aea 100644
--- a/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr
+++ b/tests/ui/stability-attribute/stability-attribute-sanity-4.stderr
@@ -1,26 +1,38 @@
-error: malformed `unstable` attribute input
+error[E0539]: malformed `unstable` attribute input
--> $DIR/stability-attribute-sanity-4.rs:8:5
|
LL | #[unstable]
- | ^^^^^^^^^^^ help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]`
+ | ^^^^^^^^^^^
+ | |
+ | expected this to be a list
+ | help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]`
-error: malformed `unstable` attribute input
+error[E0539]: malformed `unstable` attribute input
--> $DIR/stability-attribute-sanity-4.rs:11:5
|
LL | #[unstable = "b"]
- | ^^^^^^^^^^^^^^^^^ help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]`
+ | ^^^^^^^^^^^^^^^^^
+ | |
+ | expected this to be a list
+ | help: must be of the form: `#[unstable(feature = "name", reason = "...", issue = "N")]`
-error: malformed `stable` attribute input
+error[E0539]: malformed `stable` attribute input
--> $DIR/stability-attribute-sanity-4.rs:14:5
|
LL | #[stable]
- | ^^^^^^^^^ help: must be of the form: `#[stable(feature = "name", since = "version")]`
+ | ^^^^^^^^^
+ | |
+ | expected this to be a list
+ | help: must be of the form: `#[stable(feature = "name", since = "version")]`
-error: malformed `stable` attribute input
+error[E0539]: malformed `stable` attribute input
--> $DIR/stability-attribute-sanity-4.rs:17:5
|
LL | #[stable = "a"]
- | ^^^^^^^^^^^^^^^ help: must be of the form: `#[stable(feature = "name", since = "version")]`
+ | ^^^^^^^^^^^^^^^
+ | |
+ | expected this to be a list
+ | help: must be of the form: `#[stable(feature = "name", since = "version")]`
error[E0542]: missing 'since'
--> $DIR/stability-attribute-sanity-4.rs:21:5
@@ -42,5 +54,5 @@
error: aborting due to 7 previous errors
-Some errors have detailed explanations: E0542, E0543.
-For more information about an error, try `rustc --explain E0542`.
+Some errors have detailed explanations: E0539, E0542, E0543.
+For more information about an error, try `rustc --explain E0539`.
diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr
index d2dd762..60c5fb9 100644
--- a/tests/ui/statics/issue-15261.stderr
+++ b/tests/ui/statics/issue-15261.stderr
@@ -4,7 +4,7 @@
LL | static n: &'static usize = unsafe { &n_mut };
| ^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
diff --git a/tests/ui/statics/static-mut-shared-parens.stderr b/tests/ui/statics/static-mut-shared-parens.stderr
index 3825e8e..16daee0 100644
--- a/tests/ui/statics/static-mut-shared-parens.stderr
+++ b/tests/ui/statics/static-mut-shared-parens.stderr
@@ -4,7 +4,7 @@
LL | let _ = unsafe { (&TEST) as *const usize };
| ^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
@@ -18,7 +18,7 @@
LL | let _ = unsafe { (&mut TEST) as *const usize };
| ^^^^^^^^^^^ mutable reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
help: use `&raw mut` instead to create a raw pointer
|
diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr
index 2d7a055..2e5aa1b 100644
--- a/tests/ui/statics/static-mut-xc.stderr
+++ b/tests/ui/statics/static-mut-xc.stderr
@@ -4,7 +4,7 @@
LL | assert_eq!(static_mut_xc::a, 3);
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
@@ -14,7 +14,7 @@
LL | assert_eq!(static_mut_xc::a, 4);
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static
@@ -23,7 +23,7 @@
LL | assert_eq!(static_mut_xc::a, 5);
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static
@@ -32,7 +32,7 @@
LL | assert_eq!(static_mut_xc::a, 15);
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static
@@ -41,7 +41,7 @@
LL | assert_eq!(static_mut_xc::a, -3);
| ^^^^^^^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: creating a shared reference to mutable static
@@ -50,7 +50,7 @@
LL | static_bound(&static_mut_xc::a);
| ^^^^^^^^^^^^^^^^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
help: use `&raw const` instead to create a raw pointer
|
@@ -63,7 +63,7 @@
LL | static_bound_set(&mut static_mut_xc::a);
| ^^^^^^^^^^^^^^^^^^^^^ mutable reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
help: use `&raw mut` instead to create a raw pointer
|
diff --git a/tests/ui/statics/static-recursive.stderr b/tests/ui/statics/static-recursive.stderr
index 252807e..0c3f961 100644
--- a/tests/ui/statics/static-recursive.stderr
+++ b/tests/ui/statics/static-recursive.stderr
@@ -4,7 +4,7 @@
LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
| ^^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
= note: `#[warn(static_mut_refs)]` on by default
help: use `&raw const` instead to create a raw pointer
@@ -18,7 +18,7 @@
LL | assert_eq!(S, *(S as *const *const u8));
| ^ shared reference to mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html>
= note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
warning: 2 warnings emitted
diff --git a/tests/ui/suggestions/issue-116434-2015.stderr b/tests/ui/suggestions/issue-116434-2015.stderr
index cad5812..e7173d9 100644
--- a/tests/ui/suggestions/issue-116434-2015.stderr
+++ b/tests/ui/suggestions/issue-116434-2015.stderr
@@ -5,7 +5,7 @@
| ^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@
| ^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -52,7 +52,7 @@
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | fn handle() -> dyn DbHandle;
@@ -65,7 +65,7 @@
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/suggestions/issue-61963.stderr b/tests/ui/suggestions/issue-61963.stderr
index ef11efe..ffdeef1 100644
--- a/tests/ui/suggestions/issue-61963.stderr
+++ b/tests/ui/suggestions/issue-61963.stderr
@@ -5,7 +5,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
note: the lint level is defined here
--> $DIR/issue-61963.rs:4:9
|
@@ -23,7 +23,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | dyn pub struct Foo {
diff --git a/tests/ui/suggestions/option-content-move2.stderr b/tests/ui/suggestions/option-content-move2.stderr
index be97cba..436441d 100644
--- a/tests/ui/suggestions/option-content-move2.stderr
+++ b/tests/ui/suggestions/option-content-move2.stderr
@@ -2,7 +2,9 @@
--> $DIR/option-content-move2.rs:11:9
|
LL | let mut var = None;
- | ------- captured outer variable
+ | ------- ---- move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | func(|| {
| -- captured by this `FnMut` closure
LL | // Shouldn't suggest `move ||.as_ref()` here
@@ -10,16 +12,15 @@
| ^^^^^^^ `var` is moved here
LL |
LL | var = Some(NotCopyable);
- | ---
- | |
- | variable moved due to use in closure
- | move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
+ | --- variable moved due to use in closure
error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
--> $DIR/option-content-move2.rs:21:9
|
LL | let mut var = None;
- | ------- captured outer variable
+ | ------- ---- move occurs because `var` has type `Option<NotCopyableButCloneable>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | func(|| {
| -- captured by this `FnMut` closure
LL | // Shouldn't suggest `move ||.as_ref()` nor to `clone()` here
@@ -27,10 +28,7 @@
| ^^^^^^^ `var` is moved here
LL |
LL | var = Some(NotCopyableButCloneable);
- | ---
- | |
- | variable moved due to use in closure
- | move occurs because `var` has type `Option<NotCopyableButCloneable>`, which does not implement the `Copy` trait
+ | --- variable moved due to use in closure
error: aborting due to 2 previous errors
diff --git a/tests/ui/suggestions/option-content-move3.stderr b/tests/ui/suggestions/option-content-move3.stderr
index faaf8a9..68c5235 100644
--- a/tests/ui/suggestions/option-content-move3.stderr
+++ b/tests/ui/suggestions/option-content-move3.stderr
@@ -26,17 +26,16 @@
--> $DIR/option-content-move3.rs:12:9
|
LL | let var = NotCopyable;
- | --- captured outer variable
+ | --- ----------- move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | func(|| {
| -- captured by this `FnMut` closure
LL | // Shouldn't suggest `move ||.as_ref()` here
LL | move || {
| ^^^^^^^ `var` is moved here
LL | let x = var;
- | ---
- | |
- | variable moved due to use in closure
- | move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait
+ | --- variable moved due to use in closure
|
note: if `NotCopyable` implemented `Clone`, you could clone the value
--> $DIR/option-content-move3.rs:2:1
@@ -67,17 +66,16 @@
--> $DIR/option-content-move3.rs:23:9
|
LL | let var = NotCopyableButCloneable;
- | --- captured outer variable
+ | --- ----------------------- move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | func(|| {
| -- captured by this `FnMut` closure
LL | // Shouldn't suggest `move ||.as_ref()` here
LL | move || {
| ^^^^^^^ `var` is moved here
LL | let x = var;
- | ---
- | |
- | variable moved due to use in closure
- | move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait
+ | --- variable moved due to use in closure
|
help: consider cloning the value before moving it into the closure
|
diff --git a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
index 929f893..d90dd20 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
@@ -68,7 +68,7 @@
| ^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -82,7 +82,7 @@
| ^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | impl<'a, T> Enum<T> for dyn Trait<'a, T> {}
@@ -95,7 +95,7 @@
| ^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | impl<'a, T> Union<T> for dyn Trait<'a, T> {}
diff --git a/tests/ui/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr
index 9028e66..69413ca 100644
--- a/tests/ui/traits/bound/not-on-bare-trait.stderr
+++ b/tests/ui/traits/bound/not-on-bare-trait.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/traits/missing-for-type-in-impl.e2015.stderr b/tests/ui/traits/missing-for-type-in-impl.e2015.stderr
index c8a1329..a0bfc52 100644
--- a/tests/ui/traits/missing-for-type-in-impl.e2015.stderr
+++ b/tests/ui/traits/missing-for-type-in-impl.e2015.stderr
@@ -5,7 +5,7 @@
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -23,7 +23,7 @@
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is a dyn-compatible trait, use `dyn`
|
diff --git a/tests/ui/traits/unspecified-self-in-trait-ref.stderr b/tests/ui/traits/unspecified-self-in-trait-ref.stderr
index 6f5ae78..2e87245 100644
--- a/tests/ui/traits/unspecified-self-in-trait-ref.stderr
+++ b/tests/ui/traits/unspecified-self-in-trait-ref.stderr
@@ -5,7 +5,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -25,7 +25,7 @@
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let b = <dyn Foo::<_>>::lol();
@@ -44,7 +44,7 @@
| ^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let c = <dyn Bar>::lol();
@@ -63,7 +63,7 @@
| ^^^^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let d = <dyn Bar::<usize, _>>::lol();
@@ -82,7 +82,7 @@
| ^^^^^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | let e = <dyn Bar::<usize>>::lol();
diff --git a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
index 084008d..13ae6df 100644
--- a/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
+++ b/tests/ui/type-alias-enum-variants/self-in-enum-definition.stderr
@@ -9,36 +9,6 @@
|
LL | V3 = Self::V1 {} as u8 + 2,
| ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires caching mir of `Alpha::V3::{constant#0}` for CTFE...
- --> $DIR/self-in-enum-definition.rs:5:10
- |
-LL | V3 = Self::V1 {} as u8 + 2,
- | ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires elaborating drops for `Alpha::V3::{constant#0}`...
- --> $DIR/self-in-enum-definition.rs:5:10
- |
-LL | V3 = Self::V1 {} as u8 + 2,
- | ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires borrow-checking `Alpha::V3::{constant#0}`...
- --> $DIR/self-in-enum-definition.rs:5:10
- |
-LL | V3 = Self::V1 {} as u8 + 2,
- | ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires promoting constants in MIR for `Alpha::V3::{constant#0}`...
- --> $DIR/self-in-enum-definition.rs:5:10
- |
-LL | V3 = Self::V1 {} as u8 + 2,
- | ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires const checking `Alpha::V3::{constant#0}`...
- --> $DIR/self-in-enum-definition.rs:5:10
- |
-LL | V3 = Self::V1 {} as u8 + 2,
- | ^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires building MIR for `Alpha::V3::{constant#0}`...
- --> $DIR/self-in-enum-definition.rs:5:10
- |
-LL | V3 = Self::V1 {} as u8 + 2,
- | ^^^^^^^^^^^^^^^^^^^^^
= note: ...which requires computing layout of `Alpha`...
= note: ...which again requires simplifying constant for the type system `Alpha::V3::{constant#0}`, completing the cycle
note: cycle used when checking that `Alpha` is well-formed
diff --git a/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.rs b/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.rs
new file mode 100644
index 0000000..3b3ea05
--- /dev/null
+++ b/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.rs
@@ -0,0 +1,19 @@
+#[derive(Debug, Clone)]
+struct Struct { field: S }
+
+#[derive(Debug, Clone)]
+struct S;
+
+macro_rules! expand {
+ ($ident:ident) => { Struct { $ident } }
+}
+
+fn test1() {
+ let field = &S;
+ let a: Struct = dbg!(expand!(field)); //~ ERROR mismatched types [E0308]
+ let b: Struct = dbg!(Struct { field }); //~ ERROR mismatched types [E0308]
+ let c: S = dbg!(field); //~ ERROR mismatched types [E0308]
+ let c: S = dbg!(dbg!(field)); //~ ERROR mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.stderr b/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.stderr
new file mode 100644
index 0000000..59e56f6
--- /dev/null
+++ b/tests/ui/typeck/suggestions/suggest-clone-in-macro-issue-139253.stderr
@@ -0,0 +1,49 @@
+error[E0308]: mismatched types
+ --> $DIR/suggest-clone-in-macro-issue-139253.rs:13:34
+ |
+LL | let a: Struct = dbg!(expand!(field));
+ | ^^^^^ expected `S`, found `&S`
+ |
+help: consider using clone here
+ |
+LL | let a: Struct = dbg!(expand!(field: field.clone()));
+ | +++++++++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-clone-in-macro-issue-139253.rs:14:35
+ |
+LL | let b: Struct = dbg!(Struct { field });
+ | ^^^^^ expected `S`, found `&S`
+ |
+help: consider using clone here
+ |
+LL | let b: Struct = dbg!(Struct { field: field.clone() });
+ | +++++++++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-clone-in-macro-issue-139253.rs:15:16
+ |
+LL | let c: S = dbg!(field);
+ | ^^^^^^^^^^^ expected `S`, found `&S`
+ |
+ = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider using clone here
+ |
+LL | let c: S = dbg!(field).clone();
+ | ++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/suggest-clone-in-macro-issue-139253.rs:16:16
+ |
+LL | let c: S = dbg!(dbg!(field));
+ | ^^^^^^^^^^^^^^^^^ expected `S`, found `&S`
+ |
+ = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider using clone here
+ |
+LL | let c: S = dbg!(dbg!(field)).clone();
+ | ++++++++
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr b/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
index cf43913..8d9a61c 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
@@ -2,9 +2,11 @@
--> $DIR/unboxed-closure-illegal-move.rs:15:31
|
LL | let x = Box::new(0);
- | - captured outer variable
+ | - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | let f = to_fn(|| drop(x));
- | -- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | -- ^ `x` is moved here
| |
| captured by this `Fn` closure
|
@@ -17,9 +19,11 @@
--> $DIR/unboxed-closure-illegal-move.rs:19:35
|
LL | let x = Box::new(0);
- | - captured outer variable
+ | - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | let f = to_fn_mut(|| drop(x));
- | -- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | -- ^ `x` is moved here
| |
| captured by this `FnMut` closure
|
@@ -32,9 +36,11 @@
--> $DIR/unboxed-closure-illegal-move.rs:28:36
|
LL | let x = Box::new(0);
- | - captured outer variable
+ | - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | let f = to_fn(move || drop(x));
- | ------- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | ------- ^ `x` is moved here
| |
| captured by this `Fn` closure
@@ -42,9 +48,11 @@
--> $DIR/unboxed-closure-illegal-move.rs:32:40
|
LL | let x = Box::new(0);
- | - captured outer variable
+ | - ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | |
+ | captured outer variable
LL | let f = to_fn_mut(move || drop(x));
- | ------- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+ | ------- ^ `x` is moved here
| |
| captured by this `FnMut` closure
diff --git a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr
index a02c604..8a26b45 100644
--- a/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr
+++ b/tests/ui/unsafe/edition-2024-unsafe_op_in_unsafe_fn.stderr
@@ -4,7 +4,7 @@
LL | unsf();
| ^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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/edition-2024-unsafe_op_in_unsafe_fn.rs:8:1
diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr
index 2ad1de5..458a218 100644
--- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr
+++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/edition_2024_default.stderr
@@ -4,7 +4,7 @@
LL | unsf();
| ^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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/edition_2024_default.rs:11:1
diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/in_2024_compatibility.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/in_2024_compatibility.stderr
index 54447fb..0c40700 100644
--- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/in_2024_compatibility.stderr
+++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/in_2024_compatibility.stderr
@@ -4,7 +4,7 @@
LL | unsf();
| ^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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/in_2024_compatibility.rs:6:1
diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/rfc-2585-unsafe_op_in_unsafe_fn.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/rfc-2585-unsafe_op_in_unsafe_fn.stderr
index 5465c22..3e43840 100644
--- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/rfc-2585-unsafe_op_in_unsafe_fn.stderr
+++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/rfc-2585-unsafe_op_in_unsafe_fn.stderr
@@ -4,7 +4,7 @@
LL | unsf();
| ^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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/rfc-2585-unsafe_op_in_unsafe_fn.rs:8:1
@@ -23,7 +23,7 @@
LL | *PTR;
| ^^^^ dereference of raw pointer
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
error[E0133]: use of mutable static is unsafe and requires unsafe block
@@ -32,7 +32,7 @@
LL | VOID = ();
| ^^^^ use of mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
error: unnecessary `unsafe` block
@@ -53,7 +53,7 @@
LL | unsf();
| ^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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/rfc-2585-unsafe_op_in_unsafe_fn.rs:23:1
@@ -73,7 +73,7 @@
LL | *PTR;
| ^^^^ dereference of raw pointer
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
error[E0133]: use of mutable static is unsafe and requires unsafe block
@@ -82,7 +82,7 @@
LL | VOID = ();
| ^^^^ use of mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
error: unnecessary `unsafe` block
diff --git a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/wrapping-unsafe-block-sugg.stderr b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/wrapping-unsafe-block-sugg.stderr
index b48e607..f7dbf39 100644
--- a/tests/ui/unsafe/unsafe_op_in_unsafe_fn/wrapping-unsafe-block-sugg.stderr
+++ b/tests/ui/unsafe/unsafe_op_in_unsafe_fn/wrapping-unsafe-block-sugg.stderr
@@ -4,7 +4,7 @@
LL | unsf();
| ^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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/wrapping-unsafe-block-sugg.rs:11:1
@@ -23,7 +23,7 @@
LL | unsf();
| ^^^^^^ call to unsafe function
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: consult the function's documentation for information on how to avoid undefined behavior
error[E0133]: dereference of raw pointer is unsafe and requires unsafe block
@@ -32,7 +32,7 @@
LL | let y = *x;
| ^^ dereference of raw pointer
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
--> $DIR/wrapping-unsafe-block-sugg.rs:23:1
@@ -46,7 +46,7 @@
LL | y + *x
| ^^ dereference of raw pointer
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
error[E0133]: use of mutable static is unsafe and requires unsafe block
@@ -55,7 +55,7 @@
LL | let y = BAZ;
| ^^^ use of mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
note: an unsafe function restricts its caller, but its body is safe by default
--> $DIR/wrapping-unsafe-block-sugg.rs:36:1
@@ -69,7 +69,7 @@
LL | y + BAZ
| ^^^ use of mutable static
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block
@@ -81,7 +81,7 @@
LL | unsafe_macro!();
| --------------- in this macro invocation
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= 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/wrapping-unsafe-block-sugg.rs:58:1
@@ -99,7 +99,7 @@
LL | unsafe_macro!();
| --------------- in this macro invocation
|
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>
= note: consult the function's documentation for information on how to avoid undefined behavior
= note: this error originates in the macro `unsafe_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
index a99728f..26872f6 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
@@ -5,7 +5,7 @@
| ^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is a dyn-compatible trait, use `dyn`
|
@@ -19,7 +19,7 @@
| ^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+ = note: for more information, see <https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is a dyn-compatible trait, use `dyn`
|
LL | trait Bar<const M: dyn Foo<2>> {}