diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 539e33702aa67..3a33a9debaadb 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1168,7 +1168,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .span_suggestion( e.span, "consider removing the trailing pattern", - String::new(), + "", rustc_errors::Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index e27bc7a0f472f..95bf947854faf 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -139,7 +139,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .span_suggestion_verbose( sp, &format!("if you don't need to use the contents of {}, discard the tuple's remaining fields", ident), - "..".to_string(), + "..", Applicability::MaybeIncorrect, ) .emit(); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 21db7d0eebcc0..503bdbad25828 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -488,7 +488,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( replace_span, &format!("provide a definition for the {}", ctx), - sugg.to_string(), + sugg, Applicability::HasPlaceholders, ) .emit(); @@ -522,7 +522,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( span, &format!("remove the {}", remove_descr), - String::new(), + "", Applicability::MaybeIncorrect, ) .span_label(self.current_extern_span(), "`extern` block begins here") @@ -570,7 +570,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( body.span, "remove the invalid body", - ";".to_string(), + ";", Applicability::MaybeIncorrect, ) .help( @@ -599,7 +599,7 @@ impl<'a> AstValidator<'a> { .span_suggestion_verbose( span.until(ident.span.shrink_to_lo()), "remove the qualifiers", - "fn ".to_string(), + "fn ", Applicability::MaybeIncorrect, ) .emit(); @@ -703,7 +703,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( generics.span, "remove the parameters", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -721,7 +721,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( span, "remove the super traits or lifetime bounds", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -753,7 +753,7 @@ impl<'a> AstValidator<'a> { .span_suggestion( total_span, "remove these associated items", - String::new(), + "", Applicability::MachineApplicable, ) .span_label(ident_span, "auto trait cannot have associated items") @@ -993,7 +993,7 @@ fn validate_generic_param_order( err.span_suggestion( span, "reorder the parameters: lifetimes, then consts and types", - ordered_params.clone(), + &ordered_params, Applicability::MachineApplicable, ); err.emit(); diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 77dd4ccd64ef2..6db9c46dcef89 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -823,7 +823,7 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) { err.span_suggestion( attr.span, "remove the attribute", - String::new(), + "", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index c8f1e1dbb0151..bdf86825f0d8f 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -59,7 +59,7 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) { err.span_suggestion( span, "consider removing the prefix", - lint_str[1..].to_string(), + &lint_str[1..], Applicability::MaybeIncorrect, ); } @@ -942,7 +942,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { err.span_suggestion( item.span(), "supply an argument here", - "align(...)".to_string(), + "align(...)", Applicability::HasPlaceholders, ); err.emit(); diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 191574d7a8fb9..73c0bf16a1f99 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -225,7 +225,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .map(|n| format!("`{}`", n)) .unwrap_or_else(|| "the value".to_string()) ), - "ref ".to_string(), + "ref ", Applicability::MachineApplicable, ); in_pattern = true; @@ -276,7 +276,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .map(|n| format!("`{}`", n)) .unwrap_or_else(|| "the mutable reference".to_string()), ), - "&mut *".to_string(), + "&mut *", Applicability::MachineApplicable, ); } @@ -1519,15 +1519,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Ok(string) => { if string.starts_with("async ") { let pos = args_span.lo() + BytePos(6); - (args_span.with_lo(pos).with_hi(pos), "move ".to_string()) + (args_span.with_lo(pos).with_hi(pos), "move ") } else if string.starts_with("async|") { let pos = args_span.lo() + BytePos(5); - (args_span.with_lo(pos).with_hi(pos), " move".to_string()) + (args_span.with_lo(pos).with_hi(pos), " move") } else { - (args_span.shrink_to_lo(), "move ".to_string()) + (args_span.shrink_to_lo(), "move ") } } - Err(_) => (args_span, "move || ".to_string()), + Err(_) => (args_span, "move || "), }; let kind = match use_span.generator_kind() { Some(generator_kind) => match generator_kind { diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 5d9e5907dffb0..230ccf5199066 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -212,7 +212,7 @@ impl<'tcx> BorrowExplanation<'tcx> { "consider adding semicolon after the expression so its \ temporaries are dropped sooner, before the local variables \ declared by the block are dropped", - ";".to_string(), + ";", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 9581bb652362f..97e49cb472f61 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1023,7 +1023,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { avoid moving into the `for` loop", ty, ), - "&".to_string(), + "&", Applicability::MaybeIncorrect, ); } @@ -1049,7 +1049,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .map(|n| format!("`{}`", n)) .unwrap_or_else(|| "the mutable reference".to_string()), ), - "&mut *".to_string(), + "&mut *", Applicability::MachineApplicable, ); } @@ -1067,7 +1067,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_suggestion_verbose( fn_call_span.shrink_to_lo(), "consider calling `.as_ref()` to borrow the type's contents", - "as_ref().".to_string(), + "as_ref().", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index e7fd89c140fc7..eb5e61fa064bd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -417,7 +417,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), &format!("consider borrowing the `{}`'s content", diag_name.unwrap()), - ".as_ref()".to_string(), + ".as_ref()", Applicability::MaybeIncorrect, ); } else if let Some(use_spans) = use_spans { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index fe5e3c5a81b61..861c5e973f1f1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -295,7 +295,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion_verbose( source_info.span.with_hi(source_info.span.lo() + BytePos(5)), "try removing `&mut` here", - String::new(), + "", Applicability::MachineApplicable, ); } else { @@ -316,7 +316,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion_verbose( decl.source_info.span.shrink_to_lo(), "consider making the binding mutable", - "mut ".to_string(), + "mut ", Applicability::MachineApplicable, ); } @@ -402,7 +402,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion( span, "try removing `&mut` here", - String::new(), + "", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 35f805ce76e1c..e0f8da1c872d3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -860,7 +860,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement", - " + '_".to_string(), + " + '_", Applicability::MaybeIncorrect, ); suggested = true; diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index bf38ca19484c9..8ef2974c37232 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -426,7 +426,7 @@ fn do_mir_borrowck<'a, 'tcx>( .span_suggestion_short( mut_span, "remove this `mut`", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index c95d7147176bd..42bddd1b6edde 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -363,7 +363,7 @@ fn err_duplicate_option<'a>(p: &mut Parser<'a>, symbol: Symbol, span: Span) { err.tool_only_span_suggestion( full_span, "remove this option", - String::new(), + "", Applicability::MachineApplicable, ); diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 0c75187193c38..925c36edb5166 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -132,7 +132,7 @@ fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PRes err.span_suggestion( parser.token.span, "try removing semicolon", - String::new(), + "", Applicability::MaybeIncorrect, ); err.emit(); @@ -153,7 +153,7 @@ fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PRes err.span_suggestion_short( comma_span, "try adding a comma", - ", ".to_string(), + ", ", Applicability::MaybeIncorrect, ); err.emit(); diff --git a/compiler/rustc_builtin_macros/src/derive.rs b/compiler/rustc_builtin_macros/src/derive.rs index 7f25b23734b3e..d3de10ca4a2e9 100644 --- a/compiler/rustc_builtin_macros/src/derive.rs +++ b/compiler/rustc_builtin_macros/src/derive.rs @@ -142,7 +142,7 @@ fn report_path_args(sess: &Session, meta: &ast::MetaItem) { let report_error = |title, action| { let span = meta.span.with_lo(meta.path.span.hi()); sess.struct_span_err(span, title) - .span_suggestion(span, action, String::new(), Applicability::MachineApplicable) + .span_suggestion(span, action, "", Applicability::MachineApplicable) .emit(); }; match meta.kind { diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 60b96399b5e7e..10348c4967c7c 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -330,7 +330,7 @@ impl<'a, 'b> Context<'a, 'b> { err.tool_only_span_suggestion( sp, &format!("use the `{}` trait", name), - (*fmt).to_string(), + *fmt, Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 0c2d20b8f2dc8..e20375689f3d1 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -118,7 +118,7 @@ pub fn expand_test_or_bench( }; err.span_label(attr_sp, "the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions") .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr())) - .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", String::from("#[cfg(test)]"), Applicability::MaybeIncorrect) + .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", "#[cfg(test)]", Applicability::MaybeIncorrect) .emit(); return vec![Annotatable::Item(item)]; diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index c5770f505262e..e51c51cf45e5e 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -313,78 +313,82 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let a = self.read_pointer(&args[0])?; let b = self.read_pointer(&args[1])?; - // Special case: if both scalars are *equal integers* - // and not null, we pretend there is an allocation of size 0 right there, - // and their offset is 0. (There's never a valid object at null, making it an - // exception from the exception.) - // This is the dual to the special exception for offset-by-0 - // in the inbounds pointer offset operation (see `ptr_offset_inbounds` below). - match (self.ptr_try_get_alloc_id(a), self.ptr_try_get_alloc_id(b)) { - (Err(a), Err(b)) if a == b && a != 0 => { - // Both are the same non-null integer. - self.write_scalar(Scalar::from_machine_isize(0, self), dest)?; - } - (Err(offset), _) | (_, Err(offset)) => { - throw_ub!(DanglingIntPointer(offset, CheckInAllocMsg::OffsetFromTest)); - } - (Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _))) => { - // Both are pointers. They must be into the same allocation. - if a_alloc_id != b_alloc_id { - throw_ub_format!( - "{} cannot compute offset of pointers into different allocations.", - intrinsic_name, - ); + let usize_layout = self.layout_of(self.tcx.types.usize)?; + let isize_layout = self.layout_of(self.tcx.types.isize)?; + + // Get offsets for both that are at least relative to the same base. + let (a_offset, b_offset) = + match (self.ptr_try_get_alloc_id(a), self.ptr_try_get_alloc_id(b)) { + (Err(a), Err(b)) => { + // Neither poiner points to an allocation. + // If these are inequal or null, this *will* fail the deref check below. + (a, b) } - // And they must both be valid for zero-sized accesses ("in-bounds or one past the end"). - self.check_ptr_access_align( - a, - Size::ZERO, - Align::ONE, - CheckInAllocMsg::OffsetFromTest, - )?; - self.check_ptr_access_align( - b, - Size::ZERO, - Align::ONE, - CheckInAllocMsg::OffsetFromTest, - )?; - - if intrinsic_name == sym::ptr_offset_from_unsigned && a_offset < b_offset { + (Err(_), _) | (_, Err(_)) => { + // We managed to find a valid allocation for one pointer, but not the other. + // That means they are definitely not pointing to the same allocation. throw_ub_format!( - "{} cannot compute a negative offset, but {} < {}", - intrinsic_name, - a_offset.bytes(), - b_offset.bytes(), + "{} called on pointers into different allocations", + intrinsic_name ); } - - // Compute offset. - let usize_layout = self.layout_of(self.tcx.types.usize)?; - let isize_layout = self.layout_of(self.tcx.types.isize)?; - let ret_layout = if intrinsic_name == sym::ptr_offset_from { - isize_layout - } else { - usize_layout - }; - - // The subtraction is always done in `isize` to enforce - // the "no more than `isize::MAX` apart" requirement. - let a_offset = ImmTy::from_uint(a_offset.bytes(), isize_layout); - let b_offset = ImmTy::from_uint(b_offset.bytes(), isize_layout); - let (val, overflowed, _ty) = - self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?; - if overflowed { - throw_ub_format!("Pointers were too far apart for {}", intrinsic_name); + (Ok((a_alloc_id, a_offset, _)), Ok((b_alloc_id, b_offset, _))) => { + // Found allocation for both. They must be into the same allocation. + if a_alloc_id != b_alloc_id { + throw_ub_format!( + "{} called on pointers into different allocations", + intrinsic_name + ); + } + // Use these offsets for distance calculation. + (a_offset.bytes(), b_offset.bytes()) } - - let pointee_layout = self.layout_of(substs.type_at(0))?; - // This re-interprets an isize at ret_layout, but we already checked - // that if ret_layout is usize, then the result must be non-negative. - let val = ImmTy::from_scalar(val, ret_layout); - let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout); - self.exact_div(&val, &size, dest)?; + }; + + // Compute distance. + let distance = { + // The subtraction is always done in `isize` to enforce + // the "no more than `isize::MAX` apart" requirement. + let a_offset = ImmTy::from_uint(a_offset, isize_layout); + let b_offset = ImmTy::from_uint(b_offset, isize_layout); + let (val, overflowed, _ty) = + self.overflowing_binary_op(BinOp::Sub, &a_offset, &b_offset)?; + if overflowed { + throw_ub_format!("pointers were too far apart for {}", intrinsic_name); } + val.to_machine_isize(self)? + }; + + // Check that the range between them is dereferenceable ("in-bounds or one past the + // end of the same allocation"). This is like the check in ptr_offset_inbounds. + let min_ptr = if distance >= 0 { b } else { a }; + self.check_ptr_access_align( + min_ptr, + Size::from_bytes(distance.unsigned_abs()), + Align::ONE, + CheckInAllocMsg::OffsetFromTest, + )?; + + if intrinsic_name == sym::ptr_offset_from_unsigned && distance < 0 { + throw_ub_format!( + "{} called when first pointer has smaller offset than second: {} < {}", + intrinsic_name, + a_offset, + b_offset, + ); } + + // Perform division by size to compute return value. + let ret_layout = if intrinsic_name == sym::ptr_offset_from_unsigned { + usize_layout + } else { + isize_layout + }; + let pointee_layout = self.layout_of(substs.type_at(0))?; + // If ret_layout is unsigned, we checked that so is the distance, so we are good. + let val = ImmTy::from_int(distance, ret_layout); + let size = ImmTy::from_int(pointee_layout.size.bytes(), ret_layout); + self.exact_div(&val, &size, dest)?; } sym::transmute => { @@ -575,11 +579,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // memory between these pointers must be accessible. Note that we do not require the // pointers to be properly aligned (unlike a read/write operation). let min_ptr = if offset_bytes >= 0 { ptr } else { offset_ptr }; - let size = offset_bytes.unsigned_abs(); // This call handles checking for integer/null pointers. self.check_ptr_access_align( min_ptr, - Size::from_bytes(size), + Size::from_bytes(offset_bytes.unsigned_abs()), Align::ONE, CheckInAllocMsg::PointerArithmeticTest, )?; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 4b98e19376dda..b8a14e37a0990 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -1035,7 +1035,7 @@ fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol .span_suggestion( attr_span, "if it is not part of the public API, make this function unstably const", - concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(), + concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n'), Applicability::HasPlaceholders, ) .span_suggestion( diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 02d076c95ca52..fd4b2daae9c13 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,6 +1,7 @@ #![feature(let_chains)] #![feature(once_cell)] #![feature(path_try_exists)] +#![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] use fluent_bundle::FluentResource; @@ -241,6 +242,7 @@ type FluentId = Cow<'static, str>; /// message so messages of this type must be combined with a `DiagnosticMessage` (using /// `DiagnosticMessage::with_subdiagnostic_message`) before rendering. However, subdiagnostics from /// the `SessionSubdiagnostic` derive refer to Fluent identifiers directly. +#[rustc_diagnostic_item = "SubdiagnosticMessage"] pub enum SubdiagnosticMessage { /// Non-translatable diagnostic message. // FIXME(davidtwco): can a `Cow<'static, str>` be used here? @@ -281,6 +283,7 @@ impl> From for SubdiagnosticMessage { /// /// Intended to be removed once diagnostics are entirely translatable. #[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] +#[rustc_diagnostic_item = "DiagnosticMessage"] pub enum DiagnosticMessage { /// Non-translatable diagnostic message. // FIXME(davidtwco): can a `Cow<'static, str>` be used here? diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index eaceecc166778..00c0ff8bcaf9c 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -80,6 +80,7 @@ impl<'source> Into> for DiagnosticArgValue<'source> { /// Trait implemented by error types. This should not be implemented manually. Instead, use /// `#[derive(SessionSubdiagnostic)]` -- see [rustc_macros::SessionSubdiagnostic]. +#[rustc_diagnostic_item = "AddSubdiagnostic"] pub trait AddSubdiagnostic { /// Add a subdiagnostic to an existing diagnostic. fn add_to_diagnostic(self, diag: &mut Diagnostic); @@ -283,6 +284,7 @@ impl Diagnostic { /// /// This span is *not* considered a ["primary span"][`MultiSpan`]; only /// the `Span` supplied when creating the diagnostic is primary. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_label(&mut self, span: Span, label: impl Into) -> &mut Self { self.span.push_span_label(span, self.subdiagnostic_message_to_diagnostic_message(label)); self @@ -401,6 +403,7 @@ impl Diagnostic { } /// Add a note attached to this diagnostic. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn note(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Note, msg, MultiSpan::new(), None); self @@ -423,6 +426,7 @@ impl Diagnostic { /// Prints the span with a note above it. /// This is like [`Diagnostic::note()`], but it gets its own span. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_note>( &mut self, sp: S, @@ -444,6 +448,7 @@ impl Diagnostic { } /// Add a warning attached to this diagnostic. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn warn(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Warning, msg, MultiSpan::new(), None); self @@ -451,6 +456,7 @@ impl Diagnostic { /// Prints the span with a warning above it. /// This is like [`Diagnostic::warn()`], but it gets its own span. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_warn>( &mut self, sp: S, @@ -461,6 +467,7 @@ impl Diagnostic { } /// Add a help message attached to this diagnostic. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn help(&mut self, msg: impl Into) -> &mut Self { self.sub(Level::Help, msg, MultiSpan::new(), None); self @@ -474,6 +481,7 @@ impl Diagnostic { /// Prints the span with some help above it. /// This is like [`Diagnostic::help()`], but it gets its own span. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_help>( &mut self, sp: S, diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 83fe2a2df892f..8b6eba122f8f0 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -9,6 +9,7 @@ #![feature(let_else)] #![feature(never_type)] #![feature(adt_const_params)] +#![feature(rustc_attrs)] #![allow(incomplete_features)] #![allow(rustc::potential_query_instability)] @@ -648,6 +649,7 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_warn( &self, span: impl Into, @@ -659,6 +661,7 @@ impl Handler { } /// Construct a builder at the `Allow` level at the given `span` and with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_allow( &self, span: impl Into, @@ -671,6 +674,7 @@ impl Handler { /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. /// Also include a code. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_warn_with_code( &self, span: impl Into, @@ -687,16 +691,19 @@ impl Handler { /// Attempting to `.emit()` the builder will only emit if either: /// * `can_emit_warnings` is `true` /// * `is_force_warn` was set in `DiagnosticId::Lint` + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Warning, msg) } /// Construct a builder at the `Allow` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Allow, msg) } /// Construct a builder at the `Expect` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_expect( &self, msg: impl Into, @@ -706,6 +713,7 @@ impl Handler { } /// Construct a builder at the `Error` level at the given `span` and with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_err( &self, span: impl Into, @@ -717,6 +725,7 @@ impl Handler { } /// Construct a builder at the `Error` level at the given `span`, with the `msg`, and `code`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_err_with_code( &self, span: impl Into, @@ -730,6 +739,7 @@ impl Handler { /// Construct a builder at the `Error` level with the `msg`. // FIXME: This method should be removed (every error should have an associated error code). + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_err( &self, msg: impl Into, @@ -744,6 +754,7 @@ impl Handler { } /// Construct a builder at the `Error` level with the `msg` and the `code`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_err_with_code( &self, msg: impl Into, @@ -755,6 +766,7 @@ impl Handler { } /// Construct a builder at the `Warn` level with the `msg` and the `code`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_warn_with_code( &self, msg: impl Into, @@ -766,6 +778,7 @@ impl Handler { } /// Construct a builder at the `Fatal` level at the given `span` and with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_fatal( &self, span: impl Into, @@ -777,6 +790,7 @@ impl Handler { } /// Construct a builder at the `Fatal` level at the given `span`, with the `msg`, and `code`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_span_fatal_with_code( &self, span: impl Into, @@ -789,16 +803,19 @@ impl Handler { } /// Construct a builder at the `Error` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_fatal(&self, msg: impl Into) -> DiagnosticBuilder<'_, !> { DiagnosticBuilder::new_fatal(self, msg) } /// Construct a builder at the `Help` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_help(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { DiagnosticBuilder::new(self, Level::Help, msg) } /// Construct a builder at the `Note` level with the `msg`. + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_note_without_error( &self, msg: impl Into, @@ -806,11 +823,13 @@ impl Handler { DiagnosticBuilder::new(self, Level::Note, msg) } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_fatal(&self, span: impl Into, msg: impl Into) -> ! { self.emit_diag_at_span(Diagnostic::new(Fatal, msg), span); FatalError.raise() } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_fatal_with_code( &self, span: impl Into, @@ -821,6 +840,7 @@ impl Handler { FatalError.raise() } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_err( &self, span: impl Into, @@ -829,6 +849,7 @@ impl Handler { self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span).unwrap() } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_err_with_code( &self, span: impl Into, @@ -841,10 +862,12 @@ impl Handler { ); } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_warn(&self, span: impl Into, msg: impl Into) { self.emit_diag_at_span(Diagnostic::new(Warning, msg), span); } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn span_warn_with_code( &self, span: impl Into, diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index bb671b8705eb3..75b6b1cc9195b 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1194,7 +1194,7 @@ pub fn expr_to_spanned_string<'a>( err.span_suggestion( expr.span.shrink_to_lo(), "consider removing the leading `b`", - String::new(), + "", Applicability::MaybeIncorrect, ); Some((err, true)) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 5af6b777abee1..978f87b1d136e 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -945,7 +945,7 @@ pub fn ensure_complete_parse<'a>( err.span_suggestion( semi_span, "you might be missing a semicolon here", - ";".to_owned(), + ";", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index a66d36aaf72ee..f40c365cbcc18 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -102,7 +102,7 @@ fn emit_frag_parse_err( e.span_suggestion_verbose( site_span.shrink_to_hi(), "add `;` to interpret the expansion as a statement", - ";".to_string(), + ";", Applicability::MaybeIncorrect, ); } @@ -357,7 +357,7 @@ fn expand_macro<'cx>( err.span_suggestion_short( comma_span, "missing comma here", - ", ".to_string(), + ", ", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_expand/src/mbe/metavar_expr.rs b/compiler/rustc_expand/src/mbe/metavar_expr.rs index ccc1c2b2ca05b..45c462bc42504 100644 --- a/compiler/rustc_expand/src/mbe/metavar_expr.rs +++ b/compiler/rustc_expand/src/mbe/metavar_expr.rs @@ -52,7 +52,7 @@ impl MetaVarExpr { err.span_suggestion( ident.span, "supported expressions are count, ignore, index and length", - String::new(), + "", Applicability::MachineApplicable, ); return Err(err); @@ -142,7 +142,7 @@ fn parse_ident<'sess>( err.span_suggestion( token.span, &format!("try removing `{}`", &token_str), - String::new(), + "", Applicability::MaybeIncorrect, ); return Err(err); diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 35473b6e97abe..3dbaf0ddf6417 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -523,7 +523,7 @@ declare_features! ( (active, type_ascription, "1.6.0", Some(23416), None), /// Allows creation of instances of a struct by moving fields that have /// not changed from prior instances of the same struct (RFC #2528) - (incomplete, type_changing_struct_update, "1.58.0", Some(86555), None), + (active, type_changing_struct_update, "1.58.0", Some(86555), None), /// Allows unsized fn parameters. (active, unsized_fn_params, "1.49.0", Some(48055), None), /// Allows unsized rvalues at arguments and parameters. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 5eb2be97f8b92..34c53597dde6b 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -615,6 +615,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ // Used by the `rustc::potential_query_instability` lint to warn methods which // might not be stable during incremental compilation. rustc_attr!(rustc_lint_query_instability, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE), + // Used by the `rustc::untranslatable_diagnostic` and `rustc::diagnostic_outside_of_impl` lints + // to assist in changes to diagnostic APIs. + rustc_attr!(rustc_lint_diagnostics, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE), // ========================================================================== // Internal attributes, Const related: diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3eeea7fdb13e2..b94d205488d01 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -670,7 +670,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_suggestion( source_map.end_point(cause.span), "try removing this `?`", - "".to_string(), + "", Applicability::MachineApplicable, ); } @@ -726,14 +726,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_suggestion_short( sp, "consider removing this semicolon and boxing the expressions", - String::new(), + "", Applicability::MachineApplicable, ); } else { err.span_suggestion_short( sp, "consider removing this semicolon", - String::new(), + "", Applicability::MachineApplicable, ); } @@ -776,7 +776,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_suggestion_short( sp, "consider removing this semicolon", - String::new(), + "", Applicability::MachineApplicable, ); } @@ -1935,7 +1935,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { diag.span_suggestion_verbose( exp_span.shrink_to_hi(), "consider `await`ing on the `Future`", - ".await".to_string(), + ".await", Applicability::MaybeIncorrect, ); } @@ -1945,7 +1945,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { diag.span_suggestion_verbose( span.shrink_to_hi(), "consider `await`ing on the `Future`", - ".await".to_string(), + ".await", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 80500f3fe65ba..43d5c9fdf33a6 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -85,7 +85,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement", - " + '_".to_string(), + " + '_", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs index 375ad8d3736dc..76cb76d9ff4e5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs @@ -107,7 +107,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { diag.span_suggestion( new_ty_span, &format!("add explicit lifetime `{}` to {}", named, span_label_var), - new_ty.to_string(), + new_ty, Applicability::Unspecified, ); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index b856198cf3f7b..6935ce9710b6e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -328,7 +328,7 @@ pub fn suggest_new_region_bound( err.span_suggestion_verbose( span, &format!("{} `impl Trait`'s {}", consider, explicit_static), - lifetime_name.clone(), + &lifetime_name, Applicability::MaybeIncorrect, ); } @@ -363,7 +363,7 @@ pub fn suggest_new_region_bound( captures = captures, explicit = explicit, ), - plus_lt.clone(), + &plus_lt, Applicability::MaybeIncorrect, ); } @@ -378,7 +378,7 @@ pub fn suggest_new_region_bound( captures = captures, explicit = explicit, ), - plus_lt.clone(), + &plus_lt, Applicability::MaybeIncorrect, ); } @@ -391,7 +391,7 @@ pub fn suggest_new_region_bound( err.span_suggestion_verbose( lt.span, &format!("{} trait object's {}", consider, explicit_static), - lifetime_name.clone(), + &lifetime_name, Applicability::MaybeIncorrect, ); } @@ -535,7 +535,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), "consider relaxing the implicit `'static` requirement", - " + '_".to_string(), + " + '_", Applicability::MaybeIncorrect, ); suggested = true; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 3c867e308c40e..389e6483f30ff 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -449,7 +449,7 @@ pub fn configure_and_expand( .span_suggestion( first_span, "try using their name instead", - "ferris".to_string(), + "ferris", Applicability::MaybeIncorrect, ) .emit(); diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index dff2e31c6070c..b33ab40eb39cb 100644 --- a/compiler/rustc_lint/src/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs @@ -136,7 +136,7 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter { diag.span_suggestion( receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), "or remove `.into_iter()` to iterate by value", - String::new(), + "", Applicability::MaybeIncorrect, ); } else if receiver_ty.is_array() { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 205ca72aae8a8..5ef4463cb6425 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -993,7 +993,7 @@ fn lint_deprecated_attr( .span_suggestion_short( attr.span, suggestion.unwrap_or("remove this attribute"), - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -1182,7 +1182,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { .span_suggestion_short( no_mangle_attr.span, "remove this attribute", - String::new(), + "", // Use of `#[no_mangle]` suggests FFI intent; correct // fix may be to monomorphize source by hand Applicability::MaybeIncorrect, @@ -1221,7 +1221,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { err.span_suggestion( const_span, "try a static value", - "pub static".to_owned(), + "pub static", Applicability::MachineApplicable, ); err.emit(); @@ -1405,7 +1405,7 @@ impl UnreachablePub { err.span_suggestion( vis_span, "consider restricting its visibility", - "pub(crate)".to_owned(), + "pub(crate)", applicability, ); if exportable { @@ -1566,7 +1566,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { err.span_suggestion( type_alias_generics.where_clause_span, "the clause will not be checked when the type alias is used, and should be removed", - String::new(), + "", Applicability::MachineApplicable, ); if !suggested_changing_assoc_types { @@ -1830,7 +1830,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { }); } } else { - let replace = "..=".to_owned(); + let replace = "..="; if join.edition() >= Edition::Edition2021 { let mut err = rustc_errors::struct_span_err!(cx.sess(), pat.span, E0783, "{}", msg,); diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 2c6bdef361aab..2084494f7719e 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -718,7 +718,7 @@ pub trait LintContext: Sized { the macro must produce the documentation as part of its expansion"); } BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident) => { - db.span_suggestion(span, "remove `mut` from the parameter", ident.to_string(), Applicability::MachineApplicable); + db.span_suggestion(span, "remove `mut` from the parameter", ident, Applicability::MachineApplicable); } BuiltinLintDiagnostics::MissingAbi(span, default_abi) => { db.span_label(span, "ABI should be specified here"); @@ -778,7 +778,7 @@ pub trait LintContext: Sized { // Suggest the most probable if we found one if let Some(best_match) = find_best_match_for_name(&possibilities, name, None) { - db.span_suggestion(name_span, "did you mean", format!("{best_match}"), Applicability::MaybeIncorrect); + db.span_suggestion(name_span, "did you mean", best_match, Applicability::MaybeIncorrect); } }, BuiltinLintDiagnostics::UnexpectedCfg((name, name_span), Some((value, value_span))) => { @@ -805,7 +805,7 @@ pub trait LintContext: Sized { } else { db.note(&format!("no expected value for `{name}`")); if name != sym::feature { - db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", String::new(), Applicability::MaybeIncorrect); + db.span_suggestion(name_span.shrink_to_hi().to(value_span), "remove the value", "", Applicability::MaybeIncorrect); } } }, @@ -852,7 +852,7 @@ pub trait LintContext: Sized { db.span_suggestion( deletion_span, "elide the unused lifetime", - String::new(), + "", Applicability::MachineApplicable, ); }, diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index b83d63e0da086..fadb1c8793398 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -5,12 +5,14 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext} use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir::def::Res; -use rustc_hir::{Expr, ExprKind, GenericArg, PatKind, Path, PathSegment, QPath}; -use rustc_hir::{HirId, Item, ItemKind, Node, Pat, Ty, TyKind}; +use rustc_hir::{def_id::DefId, Expr, ExprKind, GenericArg, PatKind, Path, PathSegment, QPath}; +use rustc_hir::{HirId, Impl, Item, ItemKind, Node, Pat, Ty, TyKind}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::Span; +use tracing::debug; declare_tool_lint! { pub rustc::DEFAULT_HASH_TYPES, @@ -46,6 +48,41 @@ impl LateLintPass<'_> for DefaultHashTypes { } } +/// Helper function for lints that check for expressions with calls and use typeck results to +/// get the `DefId` and `SubstsRef` of the function. +fn typeck_results_of_method_fn<'tcx>( + cx: &LateContext<'tcx>, + expr: &Expr<'_>, +) -> Option<(Span, DefId, ty::subst::SubstsRef<'tcx>)> { + // FIXME(rustdoc): Lints which use this function use typecheck results which can cause + // `rustdoc` to error if there are resolution failures. + // + // As internal lints are currently always run if there are `unstable_options`, they are added + // to the lint store of rustdoc. Internal lints are also not used via the `lint_mod` query. + // Crate lints run outside of a query so rustdoc currently doesn't disable them. + // + // Instead of relying on this, either change crate lints to a query disabled by rustdoc, only + // run internal lints if the user is explicitly opting in or figure out a different way to + // avoid running lints for rustdoc. + if cx.tcx.sess.opts.actually_rustdoc { + return None; + } + + match expr.kind { + ExprKind::MethodCall(segment, _, _) + if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => + { + Some((segment.ident.span, def_id, cx.typeck_results().node_substs(expr.hir_id))) + }, + _ => { + match cx.typeck_results().node_type(expr.hir_id).kind() { + &ty::FnDef(def_id, substs) => Some((expr.span, def_id, substs)), + _ => None, + } + } + } +} + declare_tool_lint! { pub rustc::POTENTIAL_QUERY_INSTABILITY, Allow, @@ -57,35 +94,7 @@ declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY]); impl LateLintPass<'_> for QueryStability { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - // FIXME(rustdoc): This lint uses typecheck results, causing rustdoc to - // error if there are resolution failures. - // - // As internal lints are currently always run if there are `unstable_options`, - // they are added to the lint store of rustdoc. Internal lints are also - // not used via the `lint_mod` query. Crate lints run outside of a query - // so rustdoc currently doesn't disable them. - // - // Instead of relying on this, either change crate lints to a query disabled by - // rustdoc, only run internal lints if the user is explicitly opting in - // or figure out a different way to avoid running lints for rustdoc. - if cx.tcx.sess.opts.actually_rustdoc { - return; - } - - let (span, def_id, substs) = match expr.kind { - ExprKind::MethodCall(segment, _, _) - if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) => - { - (segment.ident.span, def_id, cx.typeck_results().node_substs(expr.hir_id)) - }, - _ => { - let &ty::FnDef(def_id, substs) = - cx.typeck_results() - .node_type(expr.hir_id) - .kind() else { return }; - (expr.span, def_id, substs) - } - }; + let Some((span, def_id, substs)) = typeck_results_of_method_fn(cx, expr) else { return }; if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs) { let def_id = instance.def_id(); if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { @@ -141,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { .span_suggestion( span, "try using `ty::` directly", - "ty".to_string(), + "ty", Applicability::MaybeIncorrect, // ty maybe needs an import ) .emit(); @@ -170,7 +179,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { .span_suggestion( path.span, "try using `ty::` directly", - "ty".to_string(), + "ty", Applicability::MaybeIncorrect, // ty maybe needs an import ) .emit(); @@ -188,7 +197,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { .span_suggestion( path.span, "try using `ty::` directly", - "ty".to_string(), + "ty", Applicability::MaybeIncorrect, // ty maybe needs an import ) .emit(); @@ -208,7 +217,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { .span_suggestion( path.span, "try using `ty::` directly", - "ty".to_string(), + "ty", Applicability::MaybeIncorrect, // ty maybe needs an import ) .emit(); @@ -376,3 +385,70 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword { } } } + +declare_tool_lint! { + pub rustc::UNTRANSLATABLE_DIAGNOSTIC, + Allow, + "prevent creation of diagnostics which cannot be translated", + report_in_external_macro: true +} + +declare_tool_lint! { + pub rustc::DIAGNOSTIC_OUTSIDE_OF_IMPL, + Allow, + "prevent creation of diagnostics outside of `SessionDiagnostic`/`AddSubdiagnostic` impls", + report_in_external_macro: true +} + +declare_lint_pass!(Diagnostics => [ UNTRANSLATABLE_DIAGNOSTIC, DIAGNOSTIC_OUTSIDE_OF_IMPL ]); + +impl LateLintPass<'_> for Diagnostics { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + let Some((span, def_id, substs)) = typeck_results_of_method_fn(cx, expr) else { return }; + debug!(?span, ?def_id, ?substs); + if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs) && + !cx.tcx.has_attr(instance.def_id(), sym::rustc_lint_diagnostics) + { + return; + } + + let mut found_impl = false; + for (_, parent) in cx.tcx.hir().parent_iter(expr.hir_id) { + debug!(?parent); + if let Node::Item(Item { kind: ItemKind::Impl(impl_), .. }) = parent && + let Impl { of_trait: Some(of_trait), .. } = impl_ && + let Some(def_id) = of_trait.trait_def_id() && + let Some(name) = cx.tcx.get_diagnostic_name(def_id) && + matches!(name, sym::SessionDiagnostic | sym::AddSubdiagnostic) + { + found_impl = true; + break; + } + } + debug!(?found_impl); + if !found_impl { + cx.struct_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, |lint| { + lint.build("diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls") + .emit(); + }) + } + + let mut found_diagnostic_message = false; + for ty in substs.types() { + debug!(?ty); + if let Some(adt_def) = ty.ty_adt_def() && + let Some(name) = cx.tcx.get_diagnostic_name(adt_def.did()) && + matches!(name, sym::DiagnosticMessage | sym::SubdiagnosticMessage) + { + found_diagnostic_message = true; + break; + } + } + debug!(?found_diagnostic_message); + if !found_diagnostic_message { + cx.struct_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, |lint| { + lint.build("diagnostics should be created using translatable messages").emit(); + }) + } + } +} diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 54f2c72527924..7faac5b5296d4 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -443,7 +443,7 @@ impl<'s> LintLevelsBuilder<'s> { .span_suggestion( sp, "change it to", - new_lint_name.to_string(), + new_lint_name, Applicability::MachineApplicable, ) .emit(); @@ -516,7 +516,7 @@ impl<'s> LintLevelsBuilder<'s> { err.span_suggestion( sp, "use the new name", - new_name.to_string(), + new_name, Applicability::MachineApplicable, ); } @@ -543,7 +543,7 @@ impl<'s> LintLevelsBuilder<'s> { db.span_suggestion( sp, "did you mean", - suggestion.to_string(), + suggestion, Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index ff4ed94fab339..f0182883d2b46 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -508,6 +508,8 @@ fn register_internals(store: &mut LintStore) { store.register_late_pass(|| Box::new(ExistingDocKeyword)); store.register_lints(&TyTyKind::get_lints()); store.register_late_pass(|| Box::new(TyTyKind)); + store.register_lints(&Diagnostics::get_lints()); + store.register_late_pass(|| Box::new(Diagnostics)); store.register_lints(&PassByValue::get_lints()); store.register_late_pass(|| Box::new(PassByValue)); store.register_group( diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs index 0fe6564880f01..f06a8b8f4b0c3 100644 --- a/compiler/rustc_lint/src/redundant_semicolon.rs +++ b/compiler/rustc_lint/src/redundant_semicolon.rs @@ -54,9 +54,7 @@ fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, boo } else { ("unnecessary trailing semicolon", "remove this semicolon") }; - lint.build(msg) - .span_suggestion(span, rem, String::new(), Applicability::MaybeIncorrect) - .emit(); + lint.build(msg).span_suggestion(span, rem, "", Applicability::MaybeIncorrect).emit(); }); } } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 8cae95f46dc37..73f353e62c177 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -160,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { lint.span_suggestion_verbose( expr.span.shrink_to_lo(), "use `let _ = ...` to ignore the resulting value", - "let _ = ".to_string(), + "let _ = ", Applicability::MachineApplicable, ); lint.emit(); diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 62e0fec06615e..d23707a9d316e 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -153,7 +153,7 @@ pub fn deprecation_suggestion( diag.span_suggestion( span, &format!("replace the use of the deprecated {}", kind), - suggestion.to_string(), + suggestion, Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 4006b2fcf177a..912b09eeca861 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -933,7 +933,7 @@ impl ObjectSafetyViolation { trait objects", name ), - sugg.to_string(), + sugg, Applicability::MaybeIncorrect, ); } @@ -957,7 +957,7 @@ impl ObjectSafetyViolation { "consider changing method `{}`'s `self` parameter to be `&self`", name ), - "&Self".to_string(), + "&Self", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index bec4561928cc2..273827864f1a4 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -105,7 +105,7 @@ pub(crate) fn emit_unescape_error( handler.span_suggestion( span, "consider removing the non-printing characters", - ch.to_string(), + ch, Applicability::MaybeIncorrect, ); } @@ -141,7 +141,7 @@ pub(crate) fn emit_unescape_error( .span_suggestion( char_span, "escape the character", - c.escape_default().to_string(), + c.escape_default(), Applicability::MachineApplicable, ) .emit(); @@ -157,7 +157,7 @@ pub(crate) fn emit_unescape_error( .span_suggestion( span, "escape the character", - "\\r".to_string(), + "\\r", Applicability::MachineApplicable, ) .emit(); @@ -299,7 +299,7 @@ pub(crate) fn emit_unescape_error( .span_suggestion_verbose( span.shrink_to_hi(), "terminate the unicode escape", - "}".to_string(), + "}", Applicability::MaybeIncorrect, ) .emit(); diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index faa686c3e57a3..2c68cc5895c6e 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -369,7 +369,7 @@ pub(super) fn check_for_substitution<'a>( "Unicode character '{}' ({}) looks like '{}' ({}), but it is not", ch, u_name, ascii_char, ascii_name ); - err.span_suggestion(span, &msg, ascii_char.to_string(), Applicability::MaybeIncorrect); + err.span_suggestion(span, &msg, ascii_char, Applicability::MaybeIncorrect); } token.clone() } diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index df1765952ceac..f3bdd63ee6dd4 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -282,7 +282,7 @@ fn error_malformed_cfg_attr_missing(span: Span, parse_sess: &ParseSess) { .span_suggestion( span, "missing condition and attribute", - CFG_ATTR_GRAMMAR_HELP.to_string(), + CFG_ATTR_GRAMMAR_HELP, Applicability::HasPlaceholders, ) .note(CFG_ATTR_NOTE_REF) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 3ae8bb07cd070..acdbddf4099e6 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -78,7 +78,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( replacement_span, "you might have meant to write a regular comment", - String::new(), + "", rustc_errors::Applicability::MachineApplicable, ); } @@ -200,12 +200,11 @@ impl<'a> Parser<'a> { item.kind.descr(), attr_name ), - (match attr_type { + match attr_type { OuterAttributeType::Attribute => "", OuterAttributeType::DocBlockComment => "*", OuterAttributeType::DocComment => "/", - }) - .to_string(), + }, rustc_errors::Applicability::MachineApplicable, ); return None; diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 6a44f5d6653ef..7bc8175195f40 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -431,7 +431,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( ident.span.shrink_to_lo(), &format!("escape `{}` to use it as an identifier", ident.name), - "r#".to_owned(), + "r#", Applicability::MaybeIncorrect, ); } @@ -445,7 +445,7 @@ impl<'a> Parser<'a> { err.span_suggestion( self.token.span, "remove this comma", - String::new(), + "", Applicability::MachineApplicable, ); } @@ -518,7 +518,7 @@ impl<'a> Parser<'a> { self.bump(); let sp = self.prev_token.span; self.struct_span_err(sp, &msg) - .span_suggestion_short(sp, "change this to `;`", ";".to_string(), appl) + .span_suggestion_short(sp, "change this to `;`", ";", appl) .emit(); return Ok(true); } else if self.look_ahead(0, |t| { @@ -537,7 +537,7 @@ impl<'a> Parser<'a> { let sp = self.prev_token.span.shrink_to_hi(); self.struct_span_err(sp, &msg) .span_label(self.token.span, "unexpected token") - .span_suggestion_short(sp, "add `;` here", ";".to_string(), appl) + .span_suggestion_short(sp, "add `;` here", ";", appl) .emit(); return Ok(true); } @@ -664,7 +664,7 @@ impl<'a> Parser<'a> { err.span_suggestion( span, &format!("remove the extra `#`{}", pluralize!(count)), - String::new(), + "", Applicability::MachineApplicable, ); err.span_label( @@ -761,7 +761,7 @@ impl<'a> Parser<'a> { err.span_suggestion( sp, "maybe write a path separator here", - "::".to_string(), + "::", if allow_unstable { Applicability::MaybeIncorrect } else { @@ -773,7 +773,7 @@ impl<'a> Parser<'a> { err.span_suggestion( sp, "try using a semicolon", - ";".to_string(), + ";", Applicability::MaybeIncorrect, ); } else if allow_unstable { @@ -917,7 +917,7 @@ impl<'a> Parser<'a> { .span_suggestion( span, &format!("remove extra angle bracket{}", pluralize!(total_num_of_gt)), - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -999,7 +999,7 @@ impl<'a> Parser<'a> { e.span_suggestion_verbose( binop.span.shrink_to_lo(), TURBOFISH_SUGGESTION_STR, - "::".to_string(), + "::", Applicability::MaybeIncorrect, ) .emit(); @@ -1158,7 +1158,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( op.span.shrink_to_lo(), TURBOFISH_SUGGESTION_STR, - "::".to_string(), + "::", Applicability::MaybeIncorrect, ); }; @@ -1701,7 +1701,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } - err.span_suggestion(lo.shrink_to_lo(), &format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#".to_string(), Applicability::MachineApplicable); + err.span_suggestion(lo.shrink_to_lo(), &format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); err.emit(); Ok(self.mk_expr_err(lo.to(hi))) } else { @@ -1997,7 +1997,7 @@ impl<'a> Parser<'a> { err.span_suggestion( span, "declare the type after the parameter binding", - String::from(": "), + ": ", Applicability::HasPlaceholders, ); return Some(ident); @@ -2102,7 +2102,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( pat.span, "give this argument a name or use an underscore to ignore it", - "_".to_owned(), + "_", Applicability::MachineApplicable, ) .emit(); @@ -2336,7 +2336,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( start.until(self.token.span), "the `const` keyword is only needed in the definition of the type", - String::new(), + "", Applicability::MaybeIncorrect, ); err.emit(); @@ -2394,7 +2394,7 @@ impl<'a> Parser<'a> { err.span_suggestion( snapshot.token.span, "if you meant to use an associated type binding, replace `==` with `=`", - "=".to_string(), + "=", Applicability::MaybeIncorrect, ); let value = self.mk_expr_err(start.to(expr.span)); @@ -2408,7 +2408,7 @@ impl<'a> Parser<'a> { err.span_suggestion( snapshot.token.span, "write a path separator here", - "::".to_string(), + "::", Applicability::MaybeIncorrect, ); err.emit(); @@ -2461,7 +2461,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( move_async_span, "try switching the order", - "async move".to_owned(), + "async move", Applicability::MaybeIncorrect, ); err @@ -2566,7 +2566,7 @@ impl<'a> Parser<'a> { err.span_suggestion( span, "maybe write a path separator here", - "::".to_string(), + "::", Applicability::MaybeIncorrect, ); } else { @@ -2596,7 +2596,7 @@ impl<'a> Parser<'a> { err.tool_only_span_suggestion( label.ident.span.until(self.token.span), "remove this block label", - String::new(), + "", Applicability::MachineApplicable, ); err.emit(); @@ -2669,7 +2669,7 @@ impl<'a> Parser<'a> { err.span_suggestion( between_span, "use single colon", - ": ".to_owned(), + ": ", Applicability::MachineApplicable, ); return Err(err); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 324e04b198101..236ccef1d0335 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -230,7 +230,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( sp, &format!("`{s}=` is not a valid comparison operator, use `{s}`", s = sugg), - sugg.to_string(), + sugg, Applicability::MachineApplicable, ) .emit(); @@ -247,7 +247,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( sp, "`<>` is not a valid comparison operator, use `!=`", - "!=".to_string(), + "!=", Applicability::MachineApplicable, ) .emit(); @@ -459,7 +459,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( self.token.span, &format!("use `{good}` to perform logical {english}"), - good.to_string(), + good, Applicability::MachineApplicable, ) .note("unlike in e.g., python and PHP, `&&` and `||` are used for logical operators") @@ -584,7 +584,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( lo, "try removing the `+`", - "".to_string(), + "", Applicability::MachineApplicable, ); } @@ -634,7 +634,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( lo, "use `!` to perform bitwise not", - "!".to_owned(), + "!", Applicability::MachineApplicable, ) .emit(); @@ -673,7 +673,7 @@ impl<'a> Parser<'a> { // trailing whitespace after the `!` in our suggestion self.sess.source_map().span_until_non_whitespace(lo.to(not_token.span)), "use `!` to perform logical negation", - "!".to_owned(), + "!", Applicability::MachineApplicable, ) .emit(); @@ -744,7 +744,7 @@ impl<'a> Parser<'a> { .span_suggestion( label.ident.span, "use the correct loop label format", - label.ident.to_string(), + label.ident, Applicability::MachineApplicable, ) .emit(); @@ -885,7 +885,7 @@ impl<'a> Parser<'a> { "{}remove the type ascription", if is_nightly { "alternatively, " } else { "" } ), - String::new(), + "", if is_nightly { Applicability::MaybeIncorrect } else { @@ -929,7 +929,7 @@ impl<'a> Parser<'a> { .span_suggestion( lt_span, "remove the lifetime annotation", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -1626,7 +1626,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( lo.shrink_to_hi(), "add `:` after the label", - ": ".to_string(), + ": ", Applicability::MachineApplicable, ) .note("labels are used before loops and blocks, allowing e.g., `break 'label` to them") @@ -1645,7 +1645,7 @@ impl<'a> Parser<'a> { .span_suggestion( span_dc, "replace with the new syntax", - "try".to_string(), + "try", Applicability::MachineApplicable, ) .note("following RFC #2388, the new non-placeholder syntax is `try`") @@ -2088,7 +2088,7 @@ impl<'a> Parser<'a> { .span_suggestion( span_for, "remove the parameters", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -2352,7 +2352,7 @@ impl<'a> Parser<'a> { .span_suggestion( cond.span.shrink_to_lo(), "add an `if` if this is the condition of a chained `else if` statement", - "if ".to_string(), + "if ", Applicability::MaybeIncorrect, ) .emit(); @@ -2388,12 +2388,7 @@ impl<'a> Parser<'a> { self.struct_span_err(last, "outer attributes are not allowed on `if` and `else` branches") .span_label(branch_span, "the attributes are attached to this branch") .span_label(ctx_span, format!("the branch belongs to this `{ctx}`")) - .span_suggestion( - span, - "remove the attributes", - String::new(), - Applicability::MachineApplicable, - ) + .span_suggestion(span, "remove the attributes", "", Applicability::MachineApplicable) .emit(); } @@ -2502,7 +2497,7 @@ impl<'a> Parser<'a> { e.span_suggestion_short( match_span, "try removing this `match`", - String::new(), + "", Applicability::MaybeIncorrect, // speculative ); } @@ -2578,7 +2573,7 @@ impl<'a> Parser<'a> { err.span_suggestion( semi_sp, "use a comma to end a `match` arm expression", - ",".to_string(), + ",", Applicability::MachineApplicable, ); } @@ -2679,7 +2674,7 @@ impl<'a> Parser<'a> { err.span_suggestion( this.token.span, "try using a fat arrow here", - "=>".to_string(), + "=>", Applicability::MaybeIncorrect, ); err.emit(); @@ -2739,7 +2734,7 @@ impl<'a> Parser<'a> { err.span_suggestion_short( arm_start_span.shrink_to_hi(), "missing a comma here to end this `match` arm", - ",".to_owned(), + ",", Applicability::MachineApplicable, ); return Err(err); @@ -2768,7 +2763,7 @@ impl<'a> Parser<'a> { .span_suggestion( hi.shrink_to_hi(), "missing a comma here to end this `match` arm", - ",".to_owned(), + ",", Applicability::MachineApplicable, ) .emit(); @@ -3049,7 +3044,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( self.token.span, "remove this comma", - String::new(), + "", Applicability::MachineApplicable, ) .note("the base struct must always be the last field") @@ -3103,7 +3098,7 @@ impl<'a> Parser<'a> { .span_suggestion( field_name.span.shrink_to_hi().to(self.token.span), "replace equals symbol with a colon", - ":".to_string(), + ":", Applicability::MachineApplicable, ) .emit(); @@ -3114,13 +3109,13 @@ impl<'a> Parser<'a> { .span_suggestion( span, "use `..` for an exclusive range", - "..".to_owned(), + "..", Applicability::MaybeIncorrect, ) .span_suggestion( span, "or `..=` for an inclusive range", - "..=".to_owned(), + "..=", Applicability::MaybeIncorrect, ) .emit(); @@ -3132,7 +3127,7 @@ impl<'a> Parser<'a> { span, "if you meant to write a comparison against a negative value, add a \ space in between `<` and `-`", - "< -".to_string(), + "< -", Applicability::MaybeIncorrect, ) .emit(); diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 1930dec8c3b22..1acfd93d86faf 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -271,7 +271,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( prev_token.shrink_to_hi().to(self.prev_token.span), "consider joining the two `where` clauses into one", - ",".to_owned(), + ",", Applicability::MaybeIncorrect, ); err.emit(); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 48c3c467becc8..1d50ce767afb1 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -298,7 +298,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( span, "items are imported using the `use` keyword", - "use".to_owned(), + "use", Applicability::MachineApplicable, ) .emit(); @@ -458,7 +458,7 @@ impl<'a> Parser<'a> { err.span_suggestion( path.span, "perhaps you meant to define a macro", - "macro_rules".to_string(), + "macro_rules", Applicability::MachineApplicable, ); } @@ -486,7 +486,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( self.token.span, "consider removing this semicolon", - String::new(), + "", Applicability::MaybeIncorrect, ); } @@ -606,7 +606,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( missing_for_span, "add `for` here", - " for ".to_string(), + " for ", Applicability::MachineApplicable, ) .emit(); @@ -1082,7 +1082,7 @@ impl<'a> Parser<'a> { .span_suggestion( span.with_hi(ident.span.lo()), "try using a static value", - "static ".to_string(), + "static ", Applicability::MachineApplicable, ) .note("for more information, visit https://doc.rust-lang.org/std/keyword.extern.html") @@ -1121,7 +1121,7 @@ impl<'a> Parser<'a> { .span_suggestion( const_span, "you might want to declare a static instead", - "static".to_owned(), + "static", Applicability::MaybeIncorrect, ) .emit(); @@ -1555,7 +1555,7 @@ impl<'a> Parser<'a> { err.span_suggestion_short( self.prev_token.span, "field names and their types are separated with `:`", - ":".to_string(), + ":", Applicability::MachineApplicable, ); err.emit(); @@ -1582,7 +1582,7 @@ impl<'a> Parser<'a> { .span_suggestion_verbose( self.token.span, "write a path separator here", - "::".to_string(), + "::", Applicability::MaybeIncorrect, ) .emit(); @@ -1595,7 +1595,7 @@ impl<'a> Parser<'a> { .span_suggestion( sp, "remove this unsupported default value", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -1691,7 +1691,7 @@ impl<'a> Parser<'a> { .span_suggestion( macro_rules_span, "add a `!`", - "macro_rules!".to_owned(), + "macro_rules!", Applicability::MachineApplicable, ) .emit(); @@ -1720,12 +1720,7 @@ impl<'a> Parser<'a> { // Handle macro_rules! foo! let span = self.prev_token.span; self.struct_span_err(span, "macro names aren't followed by a `!`") - .span_suggestion( - span, - "remove the `!`", - "".to_owned(), - Applicability::MachineApplicable, - ) + .span_suggestion(span, "remove the `!`", "", Applicability::MachineApplicable) .emit(); } @@ -1751,7 +1746,7 @@ impl<'a> Parser<'a> { .span_suggestion( vis.span, "try exporting the macro", - "#[macro_export]".to_owned(), + "#[macro_export]", Applicability::MaybeIncorrect, // speculative ) .emit(); @@ -1760,7 +1755,7 @@ impl<'a> Parser<'a> { .span_suggestion( vis.span, "remove the visibility", - String::new(), + "", Applicability::MachineApplicable, ) .help(&format!("try adjusting the macro to put `{vstr}` inside the invocation")) @@ -1794,14 +1789,14 @@ impl<'a> Parser<'a> { err.span_suggestion( span, "change the delimiters to curly braces", - " { /* items */ }".to_string(), + " { /* items */ }", Applicability::HasPlaceholders, ); } err.span_suggestion( span.shrink_to_hi(), "add a semicolon", - ';'.to_string(), + ';', Applicability::MaybeIncorrect, ); err.emit(); @@ -1826,7 +1821,7 @@ impl<'a> Parser<'a> { .span_suggestion( item.unwrap().span, &format!("consider creating a new `{kw_str}` definition instead of nesting"), - String::new(), + "", Applicability::MaybeIncorrect, ) .emit(); @@ -2086,7 +2081,7 @@ impl<'a> Parser<'a> { err.span_suggestion( self.token.uninterpolated_span(), &format!("`{original_kw}` already used earlier, remove this one"), - "".to_string(), + "", Applicability::MachineApplicable, ) .span_note(original_sp, &format!("`{original_kw}` first seen here")); @@ -2134,7 +2129,7 @@ impl<'a> Parser<'a> { err.span_suggestion( current_vis.span, "there is already a visibility modifier, remove one", - "".to_string(), + "", Applicability::MachineApplicable, ) .span_note(orig_vis.span, "explicit visibility first seen here"); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 6e6c1ffe74737..4df9ad26a587b 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1350,7 +1350,7 @@ impl<'a> Parser<'a> { .span_suggestion( lit.span, "specify the ABI with a string literal", - "\"C\"".to_string(), + "\"C\"", Applicability::MaybeIncorrect, ) .emit(); diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index ca7915ed17a50..ba77a39584093 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -218,12 +218,7 @@ impl<'a> Parser<'a> { if let token::OrOr = self.token.kind { let span = self.token.span; let mut err = self.struct_span_err(span, "unexpected `||` before function parameter"); - err.span_suggestion( - span, - "remove the `||`", - String::new(), - Applicability::MachineApplicable, - ); + err.span_suggestion(span, "remove the `||`", "", Applicability::MachineApplicable); err.note("alternatives in or-patterns are separated with `|`, not `||`"); err.emit(); self.bump(); @@ -287,7 +282,7 @@ impl<'a> Parser<'a> { err.span_suggestion( self.token.span, "use a single `|` to separate multiple alternative patterns", - "|".to_owned(), + "|", Applicability::MachineApplicable, ); if let Some(lo) = lo { @@ -303,7 +298,7 @@ impl<'a> Parser<'a> { err.span_suggestion( span, &format!("remove the `{}`", pprust::token_to_string(&self.token)), - String::new(), + "", Applicability::MachineApplicable, ); if let Some(lo) = lo { @@ -433,7 +428,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( lo, "for a rest pattern, use `..` instead of `...`", - "..".to_owned(), + "..", Applicability::MachineApplicable, ) .emit(); @@ -537,12 +532,7 @@ impl<'a> Parser<'a> { let span = self.prev_token.span; self.struct_span_err(span, &format!("unexpected lifetime `{}` in pattern", name)) - .span_suggestion( - span, - "remove the lifetime", - String::new(), - Applicability::MachineApplicable, - ) + .span_suggestion(span, "remove the lifetime", "", Applicability::MachineApplicable) .emit(); } } @@ -665,7 +655,7 @@ impl<'a> Parser<'a> { .span_suggestion( span, "remove the additional `mut`s", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -759,24 +749,14 @@ impl<'a> Parser<'a> { fn error_inclusive_range_with_extra_equals(&self, span: Span) { self.struct_span_err(span, "unexpected `=` after inclusive range") - .span_suggestion_short( - span, - "use `..=` instead", - "..=".to_string(), - Applicability::MaybeIncorrect, - ) + .span_suggestion_short(span, "use `..=` instead", "..=", Applicability::MaybeIncorrect) .note("inclusive ranges end with a single equals sign (`..=`)") .emit(); } fn error_inclusive_range_with_no_end(&self, span: Span) { struct_span_err!(self.sess.span_diagnostic, span, E0586, "inclusive range with no end") - .span_suggestion_short( - span, - "use `..` instead", - "..".to_string(), - Applicability::MachineApplicable, - ) + .span_suggestion_short(span, "use `..` instead", "..", Applicability::MachineApplicable) .note("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)") .emit(); } @@ -794,7 +774,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( re.span, "use `..=` instead", - "..=".to_string(), + "..=", Applicability::MachineApplicable, ) .emit(); @@ -1035,7 +1015,7 @@ impl<'a> Parser<'a> { err.span_suggestion_short( sp, "remove this comma", - String::new(), + "", Applicability::MachineApplicable, ); } @@ -1107,7 +1087,7 @@ impl<'a> Parser<'a> { .span_suggestion( self.token.span, "to omit remaining fields, use one fewer `.`", - "..".to_owned(), + "..", Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 5c6fb376cd41a..da46af60f727e 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -112,7 +112,7 @@ impl<'a> Parser<'a> { .span_suggestion( self.prev_token.span, "use double colon", - "::".to_string(), + "::", Applicability::MachineApplicable, ) .emit(); @@ -283,7 +283,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( arg.span().shrink_to_hi(), "you might have meant to end the type parameters here", - ">".to_string(), + ">", Applicability::MaybeIncorrect, ); } @@ -455,7 +455,7 @@ impl<'a> Parser<'a> { "remove extra angle bracket{}", pluralize!(snapshot.unmatched_angle_bracket_count) ), - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -489,7 +489,7 @@ impl<'a> Parser<'a> { err.span_suggestion_verbose( self.prev_token.span.until(self.token.span), "use a comma to separate type parameters", - ", ".to_string(), + ", ", Applicability::MachineApplicable, ); err.emit(); @@ -592,13 +592,13 @@ impl<'a> Parser<'a> { err.span_suggestion( self.sess.source_map().next_point(eq).to(before_next), "to constrain the associated type, add a type after `=`", - " TheType".to_string(), + " TheType", Applicability::HasPlaceholders, ); err.span_suggestion( eq.to(before_next), &format!("remove the `=` if `{}` is a type", ident), - String::new(), + "", Applicability::MaybeIncorrect, ) } else { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 7907ec44e98e9..ad0128cd9ed12 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -209,7 +209,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, Stmt> { let stmt = self.recover_local_after_let(lo, attrs)?; self.struct_span_err(lo, "invalid variable declaration") - .span_suggestion(lo, msg, sugg.to_string(), Applicability::MachineApplicable) + .span_suggestion(lo, msg, sugg, Applicability::MachineApplicable) .emit(); Ok(stmt) } @@ -287,7 +287,7 @@ impl<'a> Parser<'a> { err.span_suggestion_short( colon_sp, "use `=` if you meant to assign", - " =".to_string(), + " =", Applicability::MachineApplicable, ); err.emit(); @@ -391,7 +391,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( self.token.span, "initialize the variable", - "=".to_string(), + "=", Applicability::MaybeIncorrect, ) .help("if you meant to overwrite, remove the `let` binding") diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index dee025cfd3c8a..31b40a83e6052 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -216,7 +216,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( self.prev_token.span, "use `->` instead", - "->".to_string(), + "->", Applicability::MachineApplicable, ) .emit(); @@ -479,7 +479,7 @@ impl<'a> Parser<'a> { err.span_suggestion( span, "place `mut` before `dyn`", - "&mut dyn".to_string(), + "&mut dyn", Applicability::MachineApplicable, ); err.emit(); @@ -548,7 +548,7 @@ impl<'a> Parser<'a> { .span_suggestion_short( qual_span, &format!("remove the `{}` qualifier", qual), - String::new(), + "", Applicability::MaybeIncorrect, ) .emit(); @@ -648,7 +648,7 @@ impl<'a> Parser<'a> { .span_suggestion( self.token.span, "remove this keyword", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5cc97d326d3d8..5c3e7918aa3ff 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -118,6 +118,9 @@ impl CheckAttrVisitor<'_> { sym::rustc_lint_query_instability => { self.check_rustc_lint_query_instability(&attr, span, target) } + sym::rustc_lint_diagnostics => { + self.check_rustc_lint_diagnostics(&attr, span, target) + } sym::rustc_clean | sym::rustc_dirty | sym::rustc_if_this_changed @@ -918,7 +921,7 @@ impl CheckAttrVisitor<'_> { .span_suggestion( replacement_span, "remove this attribute", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -1158,7 +1161,7 @@ impl CheckAttrVisitor<'_> { diag.span_suggestion_short( i_meta.span, "use `notable_trait` instead", - String::from("notable_trait"), + "notable_trait", Applicability::MachineApplicable, ); diag.note("`doc(spotlight)` is now a no-op"); @@ -1624,12 +1627,9 @@ impl CheckAttrVisitor<'_> { } } - fn check_rustc_lint_query_instability( - &self, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { + /// Helper function for checking that the provided attribute is only applied to a function or + /// method. + fn check_applied_to_fn_or_method(&self, attr: &Attribute, span: Span, target: Target) -> bool { let is_function = matches!(target, Target::Fn | Target::Method(..)); if !is_function { self.tcx @@ -1643,6 +1643,23 @@ impl CheckAttrVisitor<'_> { } } + /// Checks that the `#[rustc_lint_query_instability]` attribute is only applied to a function + /// or method. + fn check_rustc_lint_query_instability( + &self, + attr: &Attribute, + span: Span, + target: Target, + ) -> bool { + self.check_applied_to_fn_or_method(attr, span, target) + } + + /// Checks that the `#[rustc_lint_diagnostics]` attribute is only applied to a function or + /// method. + fn check_rustc_lint_diagnostics(&self, attr: &Attribute, span: Span, target: Target) -> bool { + self.check_applied_to_fn_or_method(attr, span, target) + } + /// Checks that the dep-graph debugging attributes are only present when the query-dep-graph /// option is passed to the compiler. fn check_rustc_dirty_clean(&self, attr: &Attribute) -> bool { @@ -1720,7 +1737,7 @@ impl CheckAttrVisitor<'_> { .span_suggestion( attr.span, "remove this attribute", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); @@ -2259,7 +2276,7 @@ impl CheckAttrVisitor<'_> { .span_suggestion( attr.span, "remove this attribute", - String::new(), + "", Applicability::MachineApplicable, ) .note(¬e) @@ -2487,7 +2504,7 @@ fn check_duplicates( db.span_note(other, "attribute also specified here").span_suggestion( this, "remove this attribute", - String::new(), + "", Applicability::MachineApplicable, ); if matches!(duplicates, FutureWarnFollowing | FutureWarnPreceding) { @@ -2522,7 +2539,7 @@ fn check_duplicates( .span_suggestion( this, "remove this attribute", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs index e0dac09870df7..79a6e51801128 100644 --- a/compiler/rustc_passes/src/loops.rs +++ b/compiler/rustc_passes/src/loops.rs @@ -166,7 +166,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { break_expr.span, "alternatively, you might have meant to use the \ available loop label", - label.ident.to_string(), + label.ident, Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 83f728d407667..c0c696a117581 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -308,7 +308,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> { last_span, "consider specifying that the asm block is responsible \ for returning from the function", - String::from(", options(noreturn)"), + ", options(noreturn)", Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 144a60faad265..9eaefc8b8aa8f 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -125,7 +125,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { .span_suggestion_short( *span, "remove the unnecessary deprecation attribute", - String::new(), + "", rustc_errors::Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index b1fe418f687b4..3b70b90c87182 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -271,7 +271,7 @@ impl<'a> Resolver<'a> { err.tool_only_span_suggestion( import.use_span_with_attributes, "remove unnecessary import", - String::new(), + "", Applicability::MaybeIncorrect, ); } @@ -396,19 +396,14 @@ impl<'a> Resolver<'a> { // previous imports. if found_closing_brace { if let Some(span) = extend_span_to_previous_binding(self.session, span) { - err.tool_only_span_suggestion( - span, - message, - String::new(), - Applicability::MaybeIncorrect, - ); + err.tool_only_span_suggestion(span, message, "", Applicability::MaybeIncorrect); } else { // Remove the entire line if we cannot extend the span back, this indicates an // `issue_52891::{self}` case. err.span_suggestion( import.use_span_with_attributes, message, - String::new(), + "", Applicability::MaybeIncorrect, ); } @@ -416,7 +411,7 @@ impl<'a> Resolver<'a> { return; } - err.span_suggestion(span, message, String::new(), Applicability::MachineApplicable); + err.span_suggestion(span, message, "", Applicability::MachineApplicable); } pub(crate) fn lint_if_path_starts_with_module( @@ -763,7 +758,7 @@ impl<'a> Resolver<'a> { err.span_suggestion( span, "try using similarly named label", - ident.name.to_string(), + ident.name, Applicability::MaybeIncorrect, ); } @@ -796,7 +791,7 @@ impl<'a> Resolver<'a> { err.span_suggestion( span, "consider importing the module directly", - "".to_string(), + "", Applicability::MachineApplicable, ); @@ -1007,7 +1002,7 @@ impl<'a> Resolver<'a> { err.span_suggestion( span, "try using similarly named label", - ident.name.to_string(), + ident.name, Applicability::MaybeIncorrect, ); } @@ -1618,12 +1613,7 @@ impl<'a> Resolver<'a> { format!("maybe you meant this {}", suggestion.res.descr()) } }; - err.span_suggestion( - span, - &msg, - suggestion.candidate.to_string(), - Applicability::MaybeIncorrect, - ); + err.span_suggestion(span, &msg, suggestion.candidate, Applicability::MaybeIncorrect); true } @@ -2535,7 +2525,7 @@ fn show_candidates( err.span_suggestion_verbose( first.ident.span.until(last.ident.span), &format!("if you import `{}`, refer to it directly", last.ident), - String::new(), + "", Applicability::Unspecified, ); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 68ddc37c3a82b..d2306254e3142 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -280,7 +280,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion_verbose( expr_span.shrink_to_lo(), "you might have meant to use pattern matching", - "let ".to_string(), + "let ", Applicability::MaybeIncorrect, ); } @@ -294,7 +294,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion_short( span, "you might have meant to use `self` here instead", - "self".to_string(), + "self", Applicability::MaybeIncorrect, ); if !self.self_value_is_available(path[0].ident.span) { @@ -317,7 +317,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { span, "if you meant to use `self`, you are also missing a `self` receiver \ argument", - sugg.to_string(), + sugg, Applicability::MaybeIncorrect, ); } @@ -376,7 +376,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion_verbose( span, "add a `self` receiver parameter to make the associated `fn` a method", - sugg.to_string(), + sugg, Applicability::MaybeIncorrect, ); "doesn't" @@ -612,7 +612,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion_short( pat_sp.between(ty_sp), "use `=` if you meant to assign", - " = ".to_string(), + " = ", Applicability::MaybeIncorrect, ); } @@ -642,7 +642,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( span, "use the similarly named label", - label_ident.name.to_string(), + label_ident.name, Applicability::MaybeIncorrect, ); // Do not lint against unused label when we suggest them. @@ -656,7 +656,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( span, "perhaps you intended to use this type", - correct.to_string(), + correct, Applicability::MaybeIncorrect, ); } @@ -687,7 +687,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion_verbose( constraint.ident.span.between(trait_ref.span), "you might have meant to write a path instead of an associated type bound", - "::".to_string(), + "::", Applicability::MachineApplicable, ); } @@ -1079,7 +1079,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion_verbose( span.shrink_to_hi(), "use `!` to invoke the macro", - "!".to_string(), + "!", Applicability::MaybeIncorrect, ); if path_str == "try" && span.rust_2015() { @@ -1228,7 +1228,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( span, "use this syntax instead", - path_str.to_string(), + path_str, Applicability::MaybeIncorrect, ); } @@ -1507,7 +1507,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion_short( colon_sp, "maybe you meant to write `;` here", - ";".to_string(), + ";", Applicability::MaybeIncorrect, ); } else { @@ -1518,7 +1518,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_suggestion( colon_sp, "maybe you meant to write a path separator here", - "::".to_string(), + "::", Applicability::MaybeIncorrect, ); show_label = false; diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 59b4981dd0120..044be906b5507 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -5,6 +5,7 @@ #![feature(never_type)] #![feature(once_cell)] #![feature(option_get_or_insert_default)] +#![feature(rustc_attrs)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 6fb87e15a3303..a5ccae047fcc3 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -311,6 +311,7 @@ impl ParseSess { self.create_warning(warning).emit() } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_err( &self, msg: impl Into, @@ -318,6 +319,7 @@ impl ParseSess { self.span_diagnostic.struct_err(msg) } + #[cfg_attr(not(bootstrap), rustc_lint_diagnostics)] pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { self.span_diagnostic.struct_warn(msg) } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index b2c23cda6aae5..b1d1f9e7a6ce0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -209,6 +209,7 @@ pub struct PerfStats { /// Trait implemented by error types. This should not be implemented manually. Instead, use /// `#[derive(SessionDiagnostic)]` -- see [rustc_macros::SessionDiagnostic]. +#[rustc_diagnostic_item = "SessionDiagnostic"] pub trait SessionDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> { /// Write out as a diagnostic out of `sess`. #[must_use] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7b0fa65e8086b..6547ec493c862 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -125,6 +125,7 @@ symbols! { Symbols { AcqRel, Acquire, + AddSubdiagnostic, Alignment, Any, Arc, @@ -169,6 +170,7 @@ symbols! { Decoder, Default, Deref, + DiagnosticMessage, DirBuilder, Display, DoubleEndedIterator, @@ -253,11 +255,13 @@ symbols! { RustcEncodable, Send, SeqCst, + SessionDiagnostic, SliceIndex, Some, String, StructuralEq, StructuralPartialEq, + SubdiagnosticMessage, Sync, Target, ToOwned, @@ -1205,6 +1209,7 @@ symbols! { rustc_layout_scalar_valid_range_end, rustc_layout_scalar_valid_range_start, rustc_legacy_const_generics, + rustc_lint_diagnostics, rustc_lint_query_instability, rustc_macro_transparency, rustc_main, diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 0dea2c3d8bfe8..c005541ae1459 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -144,7 +144,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>( .span_suggestion_verbose( rustc_span::DUMMY_SP, "consider enabling this feature", - "#![feature(generic_const_exprs)]\n".to_string(), + "#![feature(generic_const_exprs)]\n", rustc_errors::Applicability::MaybeIncorrect, ) .emit() diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 2e7067fa71076..35daf764fff13 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -417,7 +417,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span.shrink_to_lo(), "consider converting the `Option` into a `Result` \ using `Option::ok_or` or `Option::ok_or_else`", - ".ok_or_else(|| /* error value */)".to_string(), + ".ok_or_else(|| /* error value */)", Applicability::HasPlaceholders, ); } else if should_convert_result_to_option { @@ -425,7 +425,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span.shrink_to_lo(), "consider converting the `Result` into an `Option` \ using `Result::ok`", - ".ok()".to_string(), + ".ok()", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 353547a2fb8cb..74e980b682d5d 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -701,7 +701,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_lo(), "consider dereferencing here", - "*".to_string(), + "*", Applicability::MachineApplicable, ); return true; @@ -1002,7 +1002,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { &format!( "consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`" ), - "&".to_string(), + "&", Applicability::MaybeIncorrect, ); } @@ -1059,12 +1059,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { format!("consider removing {} leading `&`-references", remove_refs) }; - err.span_suggestion_short( - sp, - &msg, - String::new(), - Applicability::MachineApplicable, - ); + err.span_suggestion_short(sp, &msg, "", Applicability::MachineApplicable); suggested = true; break; } @@ -1087,7 +1082,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion_verbose( expr.span.shrink_to_hi().with_hi(span.hi()), "remove the `.await`", - String::new(), + "", Applicability::MachineApplicable, ); // FIXME: account for associated `async fn`s. @@ -1115,14 +1110,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_lo(), &msg, - "async ".to_string(), + "async ", Applicability::MaybeIncorrect, ); } else { err.span_suggestion_verbose( vis_span.shrink_to_hi(), &msg, - " async".to_string(), + " async", Applicability::MaybeIncorrect, ); } @@ -1190,7 +1185,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion_verbose( sp, "consider changing this borrow's mutability", - "&mut ".to_string(), + "&mut ", Applicability::MachineApplicable, ); } else { @@ -1241,7 +1236,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion( self.tcx.sess.source_map().end_point(stmt.span), "remove this semicolon", - String::new(), + "", Applicability::MachineApplicable ); return true; @@ -2275,7 +2270,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_lo(), "consider borrowing here", - "&".to_owned(), + "&", Applicability::MachineApplicable, ); err.note("all local variables must have a statically known size"); @@ -2285,7 +2280,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { param.ty_span.shrink_to_lo(), "function arguments must have a statically known size, borrowed types \ always have a known size", - "&".to_owned(), + "&", Applicability::MachineApplicable, ); } @@ -2303,7 +2298,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { span.shrink_to_lo(), "function arguments must have a statically known size, borrowed types \ always have a known size", - "&".to_string(), + "&", Applicability::MachineApplicable, ); } else { @@ -2358,7 +2353,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion( span.shrink_to_lo(), "borrowed types always have a statically known size", - "&".to_string(), + "&", Applicability::MachineApplicable, ); err.multipart_suggestion( @@ -2759,7 +2754,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(), "consider `await`ing on the `Future`", - ".await".to_string(), + ".await", Applicability::MaybeIncorrect, ); } @@ -2785,7 +2780,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err.span_suggestion_verbose( rhs_span.shrink_to_hi(), "consider using a floating-point literal by writing it with `.0`", - String::from(".0"), + ".0", Applicability::MaybeIncorrect, ); } @@ -2965,7 +2960,7 @@ fn suggest_trait_object_return_type_alternatives( ret_ty, "use some type `T` that is `T: Sized` as the return type if all return paths have the \ same type", - "T".to_string(), + "T", Applicability::MaybeIncorrect, ); err.span_suggestion( diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index 8fe89c66389c2..d111008e82c83 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -161,7 +161,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_suggestion( assoc_name.span, "there is an associated type with a similar name", - suggested_name.to_string(), + suggested_name, Applicability::MaybeIncorrect, ); } else { diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index b5025b794bb0d..32bbfd7e33232 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1589,7 +1589,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_suggestion( span.shrink_to_lo(), "you are looking for the module in `std`, not the primitive type", - "std::".to_string(), + "std::", Applicability::MachineApplicable, ); } else { @@ -1820,7 +1820,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_suggestion_verbose( args_span, &format!("{type_name} doesn't have generic parameters"), - String::new(), + "", Applicability::MachineApplicable, ); return; @@ -1946,7 +1946,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_suggestion( assoc_ident.span, "there is a variant with a similar name", - suggested_name.to_string(), + suggested_name, Applicability::MaybeIncorrect, ); } else { @@ -2422,7 +2422,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_suggestion_verbose( ident.span.shrink_to_hi().to(args.span_ext), "the `Self` type doesn't accept type parameters", - String::new(), + "", Applicability::MaybeIncorrect, ); } @@ -2473,7 +2473,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_suggestion_verbose( segment.ident.span.shrink_to_hi().to(args.span_ext), "the `Self` type doesn't accept type parameters", - String::new(), + "", Applicability::MachineApplicable, ); return; @@ -2549,7 +2549,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_suggestion_verbose( segment.ident.span.shrink_to_hi().to(args.span_ext), &format!("primitive type `{name}` doesn't have generic parameters"), - String::new(), + "", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index 3632e14385fe9..bbdf1dae4a904 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -174,7 +174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.tool_only_span_suggestion( semi_span, "remove this semicolon", - String::new(), + "", Applicability::MaybeIncorrect, ); }), diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index af1288b6523be..65b8b0b97ee46 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -319,7 +319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( start, "consider separating array elements with a comma", - ",".to_string(), + ",", Applicability::MaybeIncorrect, ); return true; @@ -406,7 +406,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &format!( "`{path}` is a unit variant, you need to write it without the parentheses", ), - String::new(), + "", Applicability::MachineApplicable, ); } @@ -426,7 +426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( callee_expr.span.shrink_to_hi(), "consider using a semicolon here", - ";".to_owned(), + ";", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index d4e17f27c92bb..974f5ffcbcc52 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -354,7 +354,7 @@ fn compare_predicate_entailment<'tcx>( diag.span_suggestion_verbose(sp, msg, sugg, ap); } hir::FnRetTy::Return(hir_ty) => { - let sugg = trait_sig.output().to_string(); + let sugg = trait_sig.output(); diag.span_suggestion(hir_ty.span, msg, sugg, ap); } }; @@ -365,7 +365,7 @@ fn compare_predicate_entailment<'tcx>( diag.span_suggestion( impl_err_span, "change the parameter type to match the trait", - trait_ty.to_string(), + trait_ty, Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index bf5bd744f6298..0f5b774210e30 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -864,7 +864,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( expr.span.shrink_to_lo(), "you might have meant to use pattern destructuring", - "let ".to_string(), + "let ", Applicability::MachineApplicable, ); }); @@ -1042,7 +1042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( expr.span.shrink_to_lo(), "you might have meant to use pattern matching", - "let ".to_string(), + "let ", applicability, ); }; @@ -1051,7 +1051,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( span, "you might have meant to compare for equality", - "==".to_string(), + "==", applicability, ); } @@ -1086,7 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( lhs.span.shrink_to_lo(), "consider dereferencing here to assign to the mutably borrowed value", - "*".to_string(), + "*", Applicability::MachineApplicable, ); } @@ -1790,7 +1790,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( range_start.span.shrink_to_hi(), &format!("to set the remaining fields{instead}, separate the last named field with a comma"), - ",".to_string(), + ",", Applicability::MaybeIncorrect, ); } @@ -1912,7 +1912,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( field.ident.span, "a field with a similar name exists", - field_name.to_string(), + field_name, Applicability::MaybeIncorrect, ); } else { @@ -2158,7 +2158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( base.span.shrink_to_hi(), "consider `await`ing on the `Future` and access the field of its `Output`", - ".await".to_string(), + ".await", Applicability::MaybeIncorrect, ); } @@ -2358,7 +2358,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( field.span, "a field with a similar name exists", - suggested_field_name.to_string(), + suggested_field_name, Applicability::MaybeIncorrect, ); } else { diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index c28c041e78dff..ea7ebdf91d012 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1310,7 +1310,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( span, "use curly brackets", - String::from("Self { /* fields */ }"), + "Self { /* fields */ }", Applicability::HasPlaceholders, ); } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 0d0cc9298394e..b9077059133a0 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1458,14 +1458,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( span_semi, "consider removing this semicolon and boxing the expression", - String::new(), + "", Applicability::HasPlaceholders, ); } else { err.span_suggestion_short( span_semi, "remove this semicolon", - String::new(), + "", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 99c766d54c8aa..b01d663f605d7 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -27,7 +27,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_short( span.shrink_to_hi(), "consider using a semicolon here", - ";".to_string(), + ";", Applicability::MachineApplicable, ); } @@ -444,7 +444,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( fn_name.span, "use `Box::pin` to pin and box this expression", - "Box::pin".to_string(), + "Box::pin", Applicability::MachineApplicable, ); true @@ -507,7 +507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( expression.span.shrink_to_hi(), "consider using a semicolon here", - ";".to_string(), + ";", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 5f6ddc1e1c94a..8880049371e58 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -330,7 +330,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( span.shrink_to_lo(), "you are looking for the module in `std`, not the primitive type", - "std::".to_string(), + "std::", Applicability::MachineApplicable, ); } @@ -453,7 +453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_short( span, msg, - String::from("len"), + "len", Applicability::MachineApplicable, ); } else { @@ -893,7 +893,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { item_name.span, "because of the in-memory representation of `&str`, to obtain \ an `Iterator` over each of its codepoint use method `chars`", - String::from("chars"), + "chars", Applicability::MachineApplicable, ); } @@ -1006,7 +1006,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( span, "there is a variant with a similar name", - suggestion.to_string(), + suggestion, Applicability::MaybeIncorrect, ); } @@ -1019,12 +1019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id)); if let Some(span) = call_expr.span.trim_start(expr.span) { - err.span_suggestion( - span, - msg, - String::new(), - Applicability::MachineApplicable, - ); + err.span_suggestion(span, msg, "", Applicability::MachineApplicable); fallback_span = false; } } @@ -1043,7 +1038,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { def_kind.article(), def_kind.descr(lev_candidate.def_id), ), - lev_candidate.name.to_string(), + lev_candidate.name, Applicability::MaybeIncorrect, ); } @@ -1164,7 +1159,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( span, "remove the arguments", - String::new(), + "", Applicability::MaybeIncorrect, ); } @@ -1418,7 +1413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "use the `?` operator to extract the `{self_ty}` value, propagating \ {article} `{kind}::{variant}` value to the caller" ), - "?".to_owned(), + "?", Applicability::MachineApplicable, ); } else { @@ -1428,7 +1423,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "consider using `{kind}::expect` to unwrap the `{self_ty}` value, \ panicking if the value is {article} `{kind}::{variant}`" ), - ".expect(\"REASON\")".to_owned(), + ".expect(\"REASON\")", Applicability::HasPlaceholders, ); } @@ -1632,7 +1627,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( span.shrink_to_lo(), "consider `await`ing on the `Future` and calling the method on its `Output`", - "await.".to_string(), + "await.", Applicability::MaybeIncorrect, ); } diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs index 17a1f619ee160..c2f97a5051c96 100644 --- a/compiler/rustc_typeck/src/check/op.rs +++ b/compiler/rustc_typeck/src/check/op.rs @@ -446,7 +446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( lhs_expr.span.shrink_to_lo(), msg, - "*".to_string(), + "*", rustc_errors::Applicability::MachineApplicable, ); } @@ -621,14 +621,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( lhs_expr.span.until(lhs_inner_expr.span), rm_borrow_msg, - "".to_owned(), + "", Applicability::MachineApplicable ); } else { err.span_suggestion_verbose( lhs_expr.span.shrink_to_hi(), to_owned_msg, - ".to_owned()".to_owned(), + ".to_owned()", Applicability::MachineApplicable ); } diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 5eba95b495dd7..649558e1f662a 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1150,14 +1150,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( all_fields_span, "use `..` to ignore all fields", - String::from(".."), + "..", Applicability::MaybeIncorrect, ); } else { err.span_suggestion_verbose( tail_span, "use `..` to ignore the rest of the fields", - String::from(", .."), + ", ..", Applicability::MaybeIncorrect, ); } @@ -1428,7 +1428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( sp_comma, "add `..` at the end of the field list to ignore all other fields", - sugg.to_string(), + sugg, Applicability::MachineApplicable, ); err.emit(); @@ -1502,7 +1502,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion( pat_field.ident.span, "a field with a similar name exists", - suggested_name.to_string(), + suggested_name, Applicability::MaybeIncorrect, ); @@ -1655,7 +1655,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( field.span.shrink_to_hi(), "ignore the inaccessible and unused fields", - ", ..".to_string(), + ", ..", Applicability::MachineApplicable, ); } else { @@ -1670,7 +1670,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_suggestion_verbose( span, "ignore the inaccessible and unused fields", - " { .. }".to_string(), + " { .. }", Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs index f28184c74d355..4a3cfa1ca376a 100644 --- a/compiler/rustc_typeck/src/check_unused.rs +++ b/compiler/rustc_typeck/src/check_unused.rs @@ -122,7 +122,7 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) { .span_suggestion_short( span_with_attrs, "remove it", - String::new(), + "", Applicability::MachineApplicable, ) .emit(); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 5a70dc1e594a3..82f2adda3b043 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1930,7 +1930,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( diag.span_suggestion( ty.span, "replace with the correct return type", - ret_ty.to_string(), + ret_ty, Applicability::MachineApplicable, ); } else if matches!(ret_ty.kind(), ty::FnDef(..)) { @@ -1939,7 +1939,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( diag.span_suggestion( ty.span, "replace with the correct return type", - fn_sig.to_string(), + fn_sig, Applicability::MachineApplicable, ); } @@ -2584,7 +2584,7 @@ fn from_target_feature( let Some(list) = attr.meta_item_list() else { return }; let bad_item = |span| { let msg = "malformed `target_feature` attribute input"; - let code = "enable = \"..\"".to_owned(); + let code = "enable = \"..\""; tcx.sess .struct_span_err(span, msg) .span_suggestion(span, "must be of the form", code, Applicability::HasPlaceholders) diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 451a953691bae..d125b14feda7b 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -756,7 +756,7 @@ fn infer_placeholder_type<'a>( diag.span_suggestion( span, "replace with the correct type", - sugg_ty.to_string(), + sugg_ty, Applicability::MaybeIncorrect, ); } else { diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs index c440e93fe0af1..3224864e9b1fe 100644 --- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs @@ -715,7 +715,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { err.span_suggestion( span_redundant_lt_args, &msg_lifetimes, - String::new(), + "", Applicability::MaybeIncorrect, ); }; @@ -757,7 +757,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { err.span_suggestion( span_redundant_type_or_const_args, &msg_types_or_consts, - String::new(), + "", Applicability::MaybeIncorrect, ); }; @@ -797,7 +797,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { if self.gen_args.parenthesized { "parenthetical " } else { "" }, ); - err.span_suggestion(span, &msg, String::new(), Applicability::MaybeIncorrect); + err.span_suggestion(span, &msg, "", Applicability::MaybeIncorrect); } else if redundant_lifetime_args && redundant_type_or_const_args { remove_lifetime_args(err); remove_type_or_const_args(err); diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 9cc006b10ffc4..e3b349af661a1 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -122,7 +122,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { diag.span_suggestion( sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(), explanation, - String::from("text"), + "text", Applicability::MachineApplicable, ); } diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs new file mode 100644 index 0000000000000..817d8531da905 --- /dev/null +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs @@ -0,0 +1,73 @@ +// compile-flags: -Z unstable-options + +#![crate_type = "lib"] +#![feature(rustc_private)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] + +extern crate rustc_errors; +extern crate rustc_macros; +extern crate rustc_session; +extern crate rustc_span; + +use rustc_errors::{AddSubdiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, fluent}; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; +use rustc_session::{parse::ParseSess, SessionDiagnostic}; +use rustc_span::Span; + +#[derive(SessionDiagnostic)] +#[error(slug = "parser-expect-path")] +struct DeriveSessionDiagnostic { + #[primary_span] + span: Span, +} + +#[derive(SessionSubdiagnostic)] +#[note(slug = "note")] +struct Note { + #[primary_span] + span: Span, +} + +pub struct UntranslatableInSessionDiagnostic; + +impl<'a> SessionDiagnostic<'a, ErrorGuaranteed> for UntranslatableInSessionDiagnostic { + fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + sess.struct_err("untranslatable diagnostic") + //~^ ERROR diagnostics should be created using translatable messages + } +} + +pub struct TranslatableInSessionDiagnostic; + +impl<'a> SessionDiagnostic<'a, ErrorGuaranteed> for TranslatableInSessionDiagnostic { + fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + sess.struct_err(fluent::parser::expect_path) + } +} + +pub struct UntranslatableInAddSubdiagnostic; + +impl AddSubdiagnostic for UntranslatableInAddSubdiagnostic { + fn add_to_diagnostic(self, diag: &mut Diagnostic) { + diag.note("untranslatable diagnostic"); + //~^ ERROR diagnostics should be created using translatable messages + } +} + +pub struct TranslatableInAddSubdiagnostic; + +impl AddSubdiagnostic for TranslatableInAddSubdiagnostic { + fn add_to_diagnostic(self, diag: &mut Diagnostic) { + diag.note(fluent::typeck::note); + } +} + +pub fn make_diagnostics<'a>(sess: &'a ParseSess) { + let _diag = sess.struct_err(fluent::parser::expect_path); + //~^ ERROR diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls + + let _diag = sess.struct_err("untranslatable diagnostic"); + //~^ ERROR diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls + //~^^ ERROR diagnostics should be created using translatable messages +} diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr new file mode 100644 index 0000000000000..bae78ffdc021b --- /dev/null +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr @@ -0,0 +1,44 @@ +error: diagnostics should be created using translatable messages + --> $DIR/diagnostics.rs:36:14 + | +LL | sess.struct_err("untranslatable diagnostic") + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/diagnostics.rs:5:9 + | +LL | #![deny(rustc::untranslatable_diagnostic)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: diagnostics should be created using translatable messages + --> $DIR/diagnostics.rs:53:14 + | +LL | diag.note("untranslatable diagnostic"); + | ^^^^ + +error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls + --> $DIR/diagnostics.rs:67:22 + | +LL | let _diag = sess.struct_err(fluent::parser::expect_path); + | ^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/diagnostics.rs:6:9 + | +LL | #![deny(rustc::diagnostic_outside_of_impl)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls + --> $DIR/diagnostics.rs:70:22 + | +LL | let _diag = sess.struct_err("untranslatable diagnostic"); + | ^^^^^^^^^^ + +error: diagnostics should be created using translatable messages + --> $DIR/diagnostics.rs:70:22 + | +LL | let _diag = sess.struct_err("untranslatable diagnostic"); + | ^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics_incorrect.rs b/src/test/ui-fulldeps/internal-lints/diagnostics_incorrect.rs new file mode 100644 index 0000000000000..99f99ffcd3597 --- /dev/null +++ b/src/test/ui-fulldeps/internal-lints/diagnostics_incorrect.rs @@ -0,0 +1,15 @@ +// compile-flags: -Z unstable-options + +#![feature(rustc_attrs)] + +#[rustc_lint_diagnostics] +//~^ ERROR attribute should be applied to a function +struct Foo; + +impl Foo { + #[rustc_lint_diagnostics(a)] + //~^ ERROR malformed `rustc_lint_diagnostics` + fn bar() {} +} + +fn main() {} diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics_incorrect.stderr b/src/test/ui-fulldeps/internal-lints/diagnostics_incorrect.stderr new file mode 100644 index 0000000000000..46c206f3bf9fb --- /dev/null +++ b/src/test/ui-fulldeps/internal-lints/diagnostics_incorrect.stderr @@ -0,0 +1,17 @@ +error: malformed `rustc_lint_diagnostics` attribute input + --> $DIR/diagnostics_incorrect.rs:10:5 + | +LL | #[rustc_lint_diagnostics(a)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_lint_diagnostics]` + +error: attribute should be applied to a function + --> $DIR/diagnostics_incorrect.rs:5:1 + | +LL | #[rustc_lint_diagnostics] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | struct Foo; + | ----------- not a function + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr index 5b0b9aa9666e5..023d5ea34d871 100644 --- a/src/test/ui/const-ptr/forbidden_slices.32bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.32bit.stderr @@ -243,7 +243,7 @@ error[E0080]: could not evaluate static initializer LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | ptr_offset_from_unsigned cannot compute offset of pointers into different allocations. + | ptr_offset_from_unsigned called on pointers into different allocations | inside `ptr::const_ptr::::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -262,7 +262,7 @@ error[E0080]: could not evaluate static initializer LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | ptr_offset_from_unsigned cannot compute offset of pointers into different allocations. + | ptr_offset_from_unsigned called on pointers into different allocations | inside `ptr::const_ptr::::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL diff --git a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr index b75e6c5024667..ed89c253d532c 100644 --- a/src/test/ui/const-ptr/forbidden_slices.64bit.stderr +++ b/src/test/ui/const-ptr/forbidden_slices.64bit.stderr @@ -243,7 +243,7 @@ error[E0080]: could not evaluate static initializer LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | ptr_offset_from_unsigned cannot compute offset of pointers into different allocations. + | ptr_offset_from_unsigned called on pointers into different allocations | inside `ptr::const_ptr::::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL @@ -262,7 +262,7 @@ error[E0080]: could not evaluate static initializer LL | unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | ptr_offset_from_unsigned cannot compute offset of pointers into different allocations. + | ptr_offset_from_unsigned called on pointers into different allocations | inside `ptr::const_ptr::::sub_ptr` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | ::: $SRC_DIR/core/src/slice/raw.rs:LL:COL diff --git a/src/test/ui/consts/offset_from_ub.rs b/src/test/ui/consts/offset_from_ub.rs index f604f57e39d98..10e368ba13396 100644 --- a/src/test/ui/consts/offset_from_ub.rs +++ b/src/test/ui/consts/offset_from_ub.rs @@ -15,7 +15,7 @@ pub const DIFFERENT_ALLOC: usize = { let uninit2 = std::mem::MaybeUninit::::uninit(); let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct; let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; //~ERROR evaluation of constant value failed - //~| ptr_offset_from cannot compute offset of pointers into different allocations. + //~| pointers into different allocations offset as usize }; @@ -41,7 +41,7 @@ pub const DIFFERENT_INT: isize = { // offset_from with two different integers: l let ptr1 = 8 as *const u8; let ptr2 = 16 as *const u8; unsafe { ptr_offset_from(ptr2, ptr1) } //~ERROR evaluation of constant value failed - //~| 0x10 is not a valid pointer + //~| 0x8 is not a valid pointer }; const OUT_OF_BOUNDS_1: isize = { @@ -50,7 +50,7 @@ const OUT_OF_BOUNDS_1: isize = { let end_ptr = (start_ptr).wrapping_add(length); // First ptr is out of bounds unsafe { ptr_offset_from(end_ptr, start_ptr) } //~ERROR evaluation of constant value failed - //~| pointer at offset 10 is out-of-bounds + //~| pointer to 10 bytes starting at offset 0 is out-of-bounds }; const OUT_OF_BOUNDS_2: isize = { @@ -59,7 +59,7 @@ const OUT_OF_BOUNDS_2: isize = { let end_ptr = (start_ptr).wrapping_add(length); // Second ptr is out of bounds unsafe { ptr_offset_from(start_ptr, end_ptr) } //~ERROR evaluation of constant value failed - //~| pointer at offset 10 is out-of-bounds + //~| pointer to 10 bytes starting at offset 0 is out-of-bounds }; const OUT_OF_BOUNDS_SAME: isize = { @@ -76,7 +76,7 @@ pub const DIFFERENT_ALLOC_UNSIGNED: usize = { let uninit2 = std::mem::MaybeUninit::::uninit(); let field_ptr: *const Struct = &uninit2 as *const _ as *const Struct; let offset = unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }; //~ERROR evaluation of constant value failed - //~| ptr_offset_from_unsigned cannot compute offset of pointers into different allocations. + //~| pointers into different allocations offset as usize }; @@ -84,7 +84,7 @@ const WRONG_ORDER_UNSIGNED: usize = { let a = ['a', 'b', 'c']; let p = a.as_ptr(); unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } //~ERROR evaluation of constant value failed - //~| cannot compute a negative offset, but 0 < 8 + //~| first pointer has smaller offset than second: 0 < 8 }; fn main() {} diff --git a/src/test/ui/consts/offset_from_ub.stderr b/src/test/ui/consts/offset_from_ub.stderr index 4c98fd72cacc3..eb7f1d7a6b252 100644 --- a/src/test/ui/consts/offset_from_ub.stderr +++ b/src/test/ui/consts/offset_from_ub.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:17:27 | LL | let offset = unsafe { ptr_offset_from(field_ptr, base_ptr) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from cannot compute offset of pointers into different allocations. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from called on pointers into different allocations error[E0080]: evaluation of constant value failed --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL @@ -10,7 +10,7 @@ error[E0080]: evaluation of constant value failed LL | unsafe { intrinsics::ptr_offset_from(self, origin) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | out-of-bounds offset_from: 0x2a is not a valid pointer + | ptr_offset_from called on pointers into different allocations | inside `ptr::const_ptr::::offset_from` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL | ::: $DIR/offset_from_ub.rs:23:14 @@ -34,19 +34,19 @@ error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:43:14 | LL | unsafe { ptr_offset_from(ptr2, ptr1) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: 0x10 is not a valid pointer + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: 0x8 is not a valid pointer error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:52:14 | LL | unsafe { ptr_offset_from(end_ptr, start_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc20 has size 4, so pointer at offset 10 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc20 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:61:14 | LL | unsafe { ptr_offset_from(start_ptr, end_ptr) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc23 has size 4, so pointer at offset 10 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds offset_from: alloc23 has size 4, so pointer to 10 bytes starting at offset 0 is out-of-bounds error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:69:14 @@ -58,13 +58,13 @@ error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:78:27 | LL | let offset = unsafe { ptr_offset_from_unsigned(field_ptr, base_ptr) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from_unsigned cannot compute offset of pointers into different allocations. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from_unsigned called on pointers into different allocations error[E0080]: evaluation of constant value failed --> $DIR/offset_from_ub.rs:86:14 | LL | unsafe { ptr_offset_from_unsigned(p, p.add(2) ) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from_unsigned cannot compute a negative offset, but 0 < 8 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ptr_offset_from_unsigned called when first pointer has smaller offset than second: 0 < 8 error: aborting due to 10 previous errors diff --git a/src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs b/src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs index b364a370efab5..59a7c53540069 100644 --- a/src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs +++ b/src/tools/clippy/clippy_lints/src/almost_complete_letter_range.rs @@ -90,7 +90,7 @@ fn check_range(cx: &EarlyContext<'_>, span: Span, start: &Expr, end: &Expr, sugg diag.span_suggestion( span, "use an inclusive range", - sugg.to_owned(), + sugg, Applicability::MaybeIncorrect, ); } diff --git a/src/tools/clippy/clippy_lints/src/as_underscore.rs b/src/tools/clippy/clippy_lints/src/as_underscore.rs index 464be4218dd4d..0bdef9d0a7e8e 100644 --- a/src/tools/clippy/clippy_lints/src/as_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/as_underscore.rs @@ -63,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for AsUnderscore { diag.span_suggestion( ty.span, "consider giving the type explicitly", - format!("{}", ty_resolved), + ty_resolved, Applicability::MachineApplicable, ); } diff --git a/src/tools/clippy/clippy_lints/src/empty_structs_with_brackets.rs b/src/tools/clippy/clippy_lints/src/empty_structs_with_brackets.rs index 8430e7b4c8271..08bf80a422900 100644 --- a/src/tools/clippy/clippy_lints/src/empty_structs_with_brackets.rs +++ b/src/tools/clippy/clippy_lints/src/empty_structs_with_brackets.rs @@ -44,7 +44,7 @@ impl EarlyLintPass for EmptyStructsWithBrackets { diagnostic.span_suggestion_hidden( span_after_ident, "remove the brackets", - ";".to_string(), + ";", Applicability::MachineApplicable); }, ); diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs index 27db638813613..14f84a832aa3e 100644 --- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs +++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs @@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays { diag.span_suggestion( sugg_span, "make this a static item", - "static".to_string(), + "static", Applicability::MachineApplicable, ); } diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs index babc6fab3c0fb..c70b1c261b618 100644 --- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs +++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs @@ -86,7 +86,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { diag.span_suggestion( block.span, "move the body of the async block to the enclosing function", - body_snip.to_string(), + body_snip, Applicability::MachineApplicable ); } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index a96a7fe55f3a3..4f8baf7efb0bb 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -113,7 +113,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) { diag.span_suggestion( arm1.span, "try removing the arm", - String::new(), + "", Applicability::MaybeIncorrect, ) .help("or try changing either arm body") diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs index 90651a6ba0458..4ac738272d085 100644 --- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs +++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs @@ -176,13 +176,13 @@ fn check_manual_split_once_indirect( diag.span_suggestion( first.span, &remove_msg, - String::new(), + "", app, ); diag.span_suggestion( second.span, &remove_msg, - String::new(), + "", app, ); }); diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs index 7a39557ad5757..19037093e20a1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs @@ -85,7 +85,7 @@ pub fn check_for_loop_iter( match addr_of_expr.kind { ExprKind::AddrOf(_, _, referent) => { let span = addr_of_expr.span.with_hi(referent.span.lo()); - diag.span_suggestion(span, "remove this `&`", String::new(), applicability); + diag.span_suggestion(span, "remove this `&`", "", applicability); } _ => unreachable!(), } diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs index 26c694a71fedd..1f8c4c85cc2e1 100644 --- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs +++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs @@ -281,7 +281,7 @@ fn check<'tcx>( diag.tool_only_span_suggestion( local_stmt.span, "remove the local", - String::new(), + "", Applicability::MachineApplicable, ); @@ -318,7 +318,7 @@ fn check<'tcx>( diag.span_suggestion( usage.stmt.span.shrink_to_hi(), "add a semicolon after the `if` expression", - ";".to_string(), + ";", applicability, ); } @@ -353,7 +353,7 @@ fn check<'tcx>( diag.span_suggestion( usage.stmt.span.shrink_to_hi(), "add a semicolon after the `match` expression", - ";".to_string(), + ";", applicability, ); } 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 f423be4b67a61..8b273aca7d020 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 @@ -258,7 +258,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { diag.span_suggestion( input.span, "consider changing the type to", - "&str".to_string(), + "&str", Applicability::Unspecified, ); diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs index 249f11f985082..3b11cbc376062 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs @@ -255,7 +255,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone { diag.span_suggestion( sugg_span, "remove this", - String::new(), + "", app, ); if clone_usage.cloned_used { diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs index d5ef86dc4e572..1bde977cfa273 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs @@ -55,7 +55,7 @@ pub(super) fn check<'tcx>( sugg }; - diag.span_suggestion(e.span, "consider using", sugg.to_string(), Applicability::Unspecified); + diag.span_suggestion(e.span, "consider using", sugg, Applicability::Unspecified); }, ); true diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs index d712b33de9e1a..31a9b69ca1583 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs @@ -25,7 +25,7 @@ pub(super) fn check<'tcx>( |diag| { if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) { let sugg = arg.as_ty(cx.tcx.mk_ptr(*to_ty)); - diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified); + diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified); } }, ); diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs index 786e7bfc56f6e..707a11d361c06 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs @@ -73,7 +73,7 @@ pub(super) fn check<'tcx>( diag.span_suggestion( e.span, "try", - sugg.to_string(), + sugg, Applicability::Unspecified, ); }, diff --git a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs index a0d104e239042..fc9227b76f025 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs @@ -46,7 +46,7 @@ pub(super) fn check<'tcx>( arg.as_ty(cx.tcx.mk_ptr(rty_and_mut)).as_ty(to_ty) }; - diag.span_suggestion(e.span, "try", sugg.to_string(), Applicability::Unspecified); + diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified); } }, ); @@ -64,7 +64,7 @@ pub(super) fn check<'tcx>( diag.span_suggestion( e.span, "try", - arg.as_ty(&to_ty.to_string()).to_string(), + arg.as_ty(&to_ty.to_string()), Applicability::Unspecified, ); } diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index 49318849d5802..186bba09d2012 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -92,7 +92,7 @@ pub fn get_attr<'a>( diag.span_suggestion( attr_segments[1].ident.span, "consider using", - new_name.to_string(), + new_name, Applicability::MachineApplicable, ); diag.emit();