Auto merge of #142878 - GuillaumeGomez:rollup-53dohob, r=GuillaumeGomez

Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#142458 (Merge unboxed trait object error suggestion into regular dyn incompat error)
 - rust-lang/rust#142593 (Add a warning to LateContext::get_def_path)
 - rust-lang/rust#142594 (Add DesugaringKind::FormatLiteral)
 - rust-lang/rust#142740 (Clean-up `FnCtxt::is_destruct_assignment_desugaring`)
 - rust-lang/rust#142780 (Port `#[must_use]` to new attribute parsing infrastructure)
 - rust-lang/rust#142798 (Don't fail to parse a struct if a semicolon is used to separate fields)
 - rust-lang/rust#142856 (Add a few inline directives in rustc_serialize.)
 - rust-lang/rust#142868 (remove few allow(dead_code))
 - rust-lang/rust#142874 (cranelift: fix target feature name typo: "fxsr")
 - rust-lang/rust#142877 (Document why tidy checks if `eslint` is installed via `npm`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-06-22 17:10:28 +00:00
114 changed files with 594 additions and 515 deletions

View File

@@ -50,6 +50,14 @@ pub struct FormatArgs {
/// ///
/// Generally only useful for lints that care about the raw bytes the user wrote. /// Generally only useful for lints that care about the raw bytes the user wrote.
pub uncooked_fmt_str: (LitKind, Symbol), pub uncooked_fmt_str: (LitKind, Symbol),
/// Was the format literal written in the source?
/// - `format!("boo")` => true,
/// - `format!(concat!("b", "o", "o"))` => false,
/// - `format!(include_str!("boo.txt"))` => false,
///
/// If it wasn't written in the source then we have to be careful with spans pointing into it
/// and suggestions about rewriting it.
pub is_source_literal: bool,
} }
/// A piece of a format template string. /// A piece of a format template string.

View File

@@ -1566,7 +1566,7 @@ macro_rules! common_visitor_and_walkers {
// FIXME: visit the template exhaustively. // FIXME: visit the template exhaustively.
pub fn walk_format_args<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, fmt: &$($lt)? $($mut)? FormatArgs) -> V::Result { pub fn walk_format_args<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, fmt: &$($lt)? $($mut)? FormatArgs) -> V::Result {
let FormatArgs { span, template: _, arguments, uncooked_fmt_str: _ } = fmt; let FormatArgs { span, template: _, arguments, uncooked_fmt_str: _, is_source_literal: _ } = fmt;
let args = $(${ignore($mut)} arguments.all_args_mut())? $(${ignore($lt)} arguments.all_args())? ; let args = $(${ignore($mut)} arguments.all_args_mut())? $(${ignore($lt)} arguments.all_args())? ;
for FormatArgument { kind, expr } in args { for FormatArgument { kind, expr } in args {
match kind { match kind {

View File

@@ -4,7 +4,7 @@ use rustc_ast::*;
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_session::config::FmtDebug; use rustc_session::config::FmtDebug;
use rustc_span::{Ident, Span, Symbol, sym}; use rustc_span::{DesugaringKind, Ident, Span, Symbol, sym};
use super::LoweringContext; use super::LoweringContext;
@@ -14,6 +14,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
// format_args!() had any arguments _before_ flattening/inlining. // format_args!() had any arguments _before_ flattening/inlining.
let allow_const = fmt.arguments.all_args().is_empty(); let allow_const = fmt.arguments.all_args().is_empty();
let mut fmt = Cow::Borrowed(fmt); let mut fmt = Cow::Borrowed(fmt);
let sp = self.mark_span_with_reason(
DesugaringKind::FormatLiteral { source: fmt.is_source_literal },
sp,
sp.ctxt().outer_expn_data().allow_internal_unstable,
);
if self.tcx.sess.opts.unstable_opts.flatten_format_args { if self.tcx.sess.opts.unstable_opts.flatten_format_args {
fmt = flatten_format_args(fmt); fmt = flatten_format_args(fmt);
fmt = self.inline_literals(fmt); fmt = self.inline_literals(fmt);

View File

@@ -237,6 +237,13 @@ pub enum AttributeKind {
/// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html). /// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html).
MayDangle(Span), MayDangle(Span),
/// Represents `#[must_use]`.
MustUse {
span: Span,
/// must_use can optionally have a reason: `#[must_use = "reason this must be used"]`
reason: Option<Symbol>,
},
/// Represents `#[optimize(size|speed)]` /// Represents `#[optimize(size|speed)]`
Optimize(OptimizeAttr, Span), Optimize(OptimizeAttr, Span),

View File

@@ -33,6 +33,7 @@ pub(crate) mod confusables;
pub(crate) mod deprecation; pub(crate) mod deprecation;
pub(crate) mod inline; pub(crate) mod inline;
pub(crate) mod lint_helpers; pub(crate) mod lint_helpers;
pub(crate) mod must_use;
pub(crate) mod repr; pub(crate) mod repr;
pub(crate) mod semantics; pub(crate) mod semantics;
pub(crate) mod stability; pub(crate) mod stability;

View File

@@ -0,0 +1,40 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_errors::DiagArgValue;
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
use crate::context::{AcceptContext, Stage};
use crate::parser::ArgParser;
use crate::session_diagnostics;
pub(crate) struct MustUseParser;
impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
const PATH: &[Symbol] = &[sym::must_use];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
const TEMPLATE: AttributeTemplate = template!(Word, NameValueStr: "reason");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
Some(AttributeKind::MustUse {
span: cx.attr_span,
reason: match args {
ArgParser::NoArgs => None,
ArgParser::NameValue(name_value) => name_value.value_as_str(),
ArgParser::List(_) => {
let suggestions =
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "must_use");
cx.emit_err(session_diagnostics::MustUseIllFormedAttributeInput {
num_suggestions: suggestions.len(),
suggestions: DiagArgValue::StrListSepByAnd(
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
),
span: cx.attr_span,
});
return None;
}
},
})
}
}

View File

@@ -20,6 +20,7 @@ use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::deprecation::DeprecationParser; use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser}; use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser};
use crate::attributes::must_use::MustUseParser;
use crate::attributes::repr::{AlignParser, ReprParser}; use crate::attributes::repr::{AlignParser, ReprParser};
use crate::attributes::semantics::MayDangleParser; use crate::attributes::semantics::MayDangleParser;
use crate::attributes::stability::{ use crate::attributes::stability::{
@@ -112,6 +113,7 @@ attribute_parsers!(
Single<DeprecationParser>, Single<DeprecationParser>,
Single<InlineParser>, Single<InlineParser>,
Single<MayDangleParser>, Single<MayDangleParser>,
Single<MustUseParser>,
Single<OptimizeParser>, Single<OptimizeParser>,
Single<PubTransparentParser>, Single<PubTransparentParser>,
Single<RustcForceInlineParser>, Single<RustcForceInlineParser>,

View File

@@ -436,6 +436,15 @@ pub(crate) struct IllFormedAttributeInput {
pub suggestions: DiagArgValue, pub suggestions: DiagArgValue,
} }
#[derive(Diagnostic)]
#[diag(attr_parsing_ill_formed_attribute_input)]
pub(crate) struct MustUseIllFormedAttributeInput {
#[primary_span]
pub span: Span,
pub num_suggestions: usize,
pub suggestions: DiagArgValue,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(attr_parsing_stability_outside_std, code = E0734)] #[diag(attr_parsing_stability_outside_std, code = E0734)]
pub(crate) struct StabilityOutsideStd { pub(crate) struct StabilityOutsideStd {

View File

@@ -606,6 +606,7 @@ fn make_format_args(
template, template,
arguments: args, arguments: args,
uncooked_fmt_str, uncooked_fmt_str,
is_source_literal,
})) }))
} }

View File

@@ -184,7 +184,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
// FIXME return the actually used target features. this is necessary for #[cfg(target_feature)] // FIXME return the actually used target features. this is necessary for #[cfg(target_feature)]
let target_features = if sess.target.arch == "x86_64" && sess.target.os != "none" { let target_features = if sess.target.arch == "x86_64" && sess.target.os != "none" {
// x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled // x86_64 mandates SSE2 support and rustc requires the x87 feature to be enabled
vec![sym::fsxr, sym::sse, sym::sse2, Symbol::intern("x87")] vec![sym::fxsr, sym::sse, sym::sse2, Symbol::intern("x87")]
} else if sess.target.arch == "aarch64" { } else if sess.target.arch == "aarch64" {
match &*sess.target.os { match &*sess.target.os {
"none" => vec![], "none" => vec![],

View File

@@ -1,8 +1,6 @@
//! This module implements a lock which only uses synchronization if `might_be_dyn_thread_safe` is true. //! This module implements a lock which only uses synchronization if `might_be_dyn_thread_safe` is true.
//! It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync` traits. //! It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync` traits.
#![allow(dead_code)]
use std::fmt; use std::fmt;
#[derive(Clone, Copy, PartialEq)] #[derive(Clone, Copy, PartialEq)]

View File

@@ -1,8 +1,6 @@
//! This module defines parallel operations that are implemented in //! This module defines parallel operations that are implemented in
//! one way for the serial compiler, and another way the parallel compiler. //! one way for the serial compiler, and another way the parallel compiler.
#![allow(dead_code)]
use std::any::Any; use std::any::Any;
use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind}; use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};

View File

@@ -382,8 +382,6 @@ fn check_trait_item<'tcx>(
_ => (None, trait_item.span), _ => (None, trait_item.span),
}; };
check_dyn_incompatible_self_trait_by_name(tcx, trait_item);
// Check that an item definition in a subtrait is shadowing a supertrait item. // Check that an item definition in a subtrait is shadowing a supertrait item.
lint_item_shadowing_supertrait_item(tcx, def_id); lint_item_shadowing_supertrait_item(tcx, def_id);
@@ -832,70 +830,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
} }
} }
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
match ty.kind {
hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
[s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
_ => false,
},
_ => false,
}
}
/// Detect when a dyn-incompatible trait is referring to itself in one of its associated items.
///
/// In such cases, suggest using `Self` instead.
fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) {
let (trait_ident, trait_def_id) =
match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(item.hir_id()).def_id) {
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Trait(_, _, ident, ..) => (ident, item.owner_id),
_ => return,
},
_ => return,
};
let mut trait_should_be_self = vec![];
match &item.kind {
hir::TraitItemKind::Const(ty, _) | hir::TraitItemKind::Type(_, Some(ty))
if could_be_self(trait_def_id.def_id, ty) =>
{
trait_should_be_self.push(ty.span)
}
hir::TraitItemKind::Fn(sig, _) => {
for ty in sig.decl.inputs {
if could_be_self(trait_def_id.def_id, ty) {
trait_should_be_self.push(ty.span);
}
}
match sig.decl.output {
hir::FnRetTy::Return(ty) if could_be_self(trait_def_id.def_id, ty) => {
trait_should_be_self.push(ty.span);
}
_ => {}
}
}
_ => {}
}
if !trait_should_be_self.is_empty() {
if tcx.is_dyn_compatible(trait_def_id) {
return;
}
let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect();
tcx.dcx()
.struct_span_err(
trait_should_be_self,
"associated item referring to unboxed trait object for its own trait",
)
.with_span_label(trait_ident.span, "in this trait")
.with_multipart_suggestion(
"you might have meant to use `Self` to refer to the implementing type",
sugg,
Applicability::MachineApplicable,
)
.emit();
}
}
fn lint_item_shadowing_supertrait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_def_id: LocalDefId) { fn lint_item_shadowing_supertrait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_def_id: LocalDefId) {
let item_name = tcx.item_name(trait_item_def_id.to_def_id()); let item_name = tcx.item_name(trait_item_def_id.to_def_id());
let trait_def_id = tcx.local_parent(trait_item_def_id); let trait_def_id = tcx.local_parent(trait_item_def_id);

View File

@@ -1,7 +1,8 @@
use rustc_hir::def::DefKind;
use rustc_hir::intravisit::{self, Visitor, VisitorExt}; use rustc_hir::intravisit::{self, Visitor, VisitorExt};
use rustc_hir::{self as hir, AmbigArg, ForeignItem, ForeignItemKind}; use rustc_hir::{self as hir, AmbigArg, ForeignItem, ForeignItemKind};
use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_infer::traits::{ObligationCause, ObligationCauseCode, WellFormedLoc};
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode, fold_regions}; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode, fold_regions};
@@ -107,6 +108,17 @@ fn diagnostic_hir_wf_check<'tcx>(
// over less-specific types (e.g. `Option<MyStruct<u8>>`) // over less-specific types (e.g. `Option<MyStruct<u8>>`)
if self.depth >= self.cause_depth { if self.depth >= self.cause_depth {
self.cause = Some(error.obligation.cause); self.cause = Some(error.obligation.cause);
if let hir::TyKind::TraitObject(..) = ty.kind {
if let DefKind::AssocTy | DefKind::AssocConst | DefKind::AssocFn =
self.tcx.def_kind(self.def_id)
{
self.cause = Some(ObligationCause::new(
ty.span,
self.def_id,
ObligationCauseCode::DynCompatible(ty.span),
));
}
}
self.cause_depth = self.depth self.cause_depth = self.depth
} }
} }

View File

@@ -1110,28 +1110,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
// Returns whether the given expression is a destruct assignment desugaring. /// Returns whether the given expression is a destruct assignment desugaring.
// For example, `(a, b) = (1, &2);` /// For example, `(a, b) = (1, &2);`
// Here we try to find the pattern binding of the expression, /// Here we try to find the pattern binding of the expression,
// `default_binding_modes` is false only for destruct assignment desugaring. /// `default_binding_modes` is false only for destruct assignment desugaring.
pub(crate) fn is_destruct_assignment_desugaring(&self, expr: &hir::Expr<'_>) -> bool { pub(crate) fn is_destruct_assignment_desugaring(&self, expr: &hir::Expr<'_>) -> bool {
if let hir::ExprKind::Path(hir::QPath::Resolved( if let hir::ExprKind::Path(hir::QPath::Resolved(
_, _,
hir::Path { res: hir::def::Res::Local(bind_hir_id), .. }, hir::Path { res: hir::def::Res::Local(bind_hir_id), .. },
)) = expr.kind )) = expr.kind
{ && let bind = self.tcx.hir_node(*bind_hir_id)
let bind = self.tcx.hir_node(*bind_hir_id); && let parent = self.tcx.parent_hir_node(*bind_hir_id)
let parent = self.tcx.parent_hir_node(*bind_hir_id); && let hir::Node::Pat(hir::Pat {
if let hir::Node::Pat(hir::Pat {
kind: hir::PatKind::Binding(_, _hir_id, _, _), .. kind: hir::PatKind::Binding(_, _hir_id, _, _), ..
}) = bind }) = bind
&& let hir::Node::Pat(hir::Pat { default_binding_modes: false, .. }) = parent && let hir::Node::Pat(hir::Pat { default_binding_modes: false, .. }) = parent
{ {
return true; true
} } else {
}
false false
} }
}
fn explain_self_literal( fn explain_self_literal(
&self, &self,

View File

@@ -711,6 +711,15 @@ impl<'tcx> LateContext<'tcx> {
/// Gets the absolute path of `def_id` as a vector of `Symbol`. /// Gets the absolute path of `def_id` as a vector of `Symbol`.
/// ///
/// Note that this is kinda expensive because it has to
/// travel the tree and pretty-print. Use sparingly.
///
/// If you're trying to match for an item given by its path, use a
/// diagnostic item. If you're only interested in given sections, use more
/// specific functions, such as [`TyCtxt::crate_name`]
///
/// FIXME: It would be great if this could be optimized.
///
/// # Examples /// # Examples
/// ///
/// ```rust,ignore (no context or def id available) /// ```rust,ignore (no context or def id available)

View File

@@ -2,6 +2,7 @@ use std::iter;
use rustc_ast::util::{classify, parser}; use rustc_ast::util::{classify, parser};
use rustc_ast::{self as ast, ExprKind, HasAttrs as _, StmtKind}; use rustc_ast::{self as ast, ExprKind, HasAttrs as _, StmtKind};
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_errors::{MultiSpan, pluralize}; use rustc_errors::{MultiSpan, pluralize};
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@@ -368,10 +369,12 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
} }
fn is_def_must_use(cx: &LateContext<'_>, def_id: DefId, span: Span) -> Option<MustUsePath> { fn is_def_must_use(cx: &LateContext<'_>, def_id: DefId, span: Span) -> Option<MustUsePath> {
if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) { if let Some(reason) = find_attr!(
cx.tcx.get_all_attrs(def_id),
AttributeKind::MustUse { reason, .. } => reason
) {
// check for #[must_use = "..."] // check for #[must_use = "..."]
let reason = attr.value_str(); Some(MustUsePath::Def(span, def_id, *reason))
Some(MustUsePath::Def(span, def_id, reason))
} else { } else {
None None
} }

View File

@@ -397,6 +397,8 @@ pub enum ObligationCauseCode<'tcx> {
RustCall, RustCall,
DynCompatible(Span),
/// Obligations to prove that a `Drop` or negative auto trait impl is not stronger than /// Obligations to prove that a `Drop` or negative auto trait impl is not stronger than
/// the ADT it's being implemented for. /// the ADT it's being implemented for.
AlwaysApplicableImpl, AlwaysApplicableImpl,

View File

@@ -1781,7 +1781,7 @@ impl<'a> Parser<'a> {
let mut recovered = Recovered::No; let mut recovered = Recovered::No;
if self.eat(exp!(OpenBrace)) { if self.eat(exp!(OpenBrace)) {
while self.token != token::CloseBrace { while self.token != token::CloseBrace {
match self.parse_field_def(adt_ty) { match self.parse_field_def(adt_ty, ident_span) {
Ok(field) => { Ok(field) => {
fields.push(field); fields.push(field);
} }
@@ -1894,7 +1894,7 @@ impl<'a> Parser<'a> {
} }
/// Parses an element of a struct declaration. /// Parses an element of a struct declaration.
fn parse_field_def(&mut self, adt_ty: &str) -> PResult<'a, FieldDef> { fn parse_field_def(&mut self, adt_ty: &str, ident_span: Span) -> PResult<'a, FieldDef> {
self.recover_vcs_conflict_marker(); self.recover_vcs_conflict_marker();
let attrs = self.parse_outer_attributes()?; let attrs = self.parse_outer_attributes()?;
self.recover_vcs_conflict_marker(); self.recover_vcs_conflict_marker();
@@ -1902,7 +1902,7 @@ impl<'a> Parser<'a> {
let lo = this.token.span; let lo = this.token.span;
let vis = this.parse_visibility(FollowedByType::No)?; let vis = this.parse_visibility(FollowedByType::No)?;
let safety = this.parse_unsafe_field(); let safety = this.parse_unsafe_field();
this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs) this.parse_single_struct_field(adt_ty, lo, vis, safety, attrs, ident_span)
.map(|field| (field, Trailing::No, UsePreAttrPos::No)) .map(|field| (field, Trailing::No, UsePreAttrPos::No))
}) })
} }
@@ -1915,13 +1915,15 @@ impl<'a> Parser<'a> {
vis: Visibility, vis: Visibility,
safety: Safety, safety: Safety,
attrs: AttrVec, attrs: AttrVec,
ident_span: Span,
) -> PResult<'a, FieldDef> { ) -> PResult<'a, FieldDef> {
let mut seen_comma: bool = false;
let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?; let a_var = self.parse_name_and_ty(adt_ty, lo, vis, safety, attrs)?;
if self.token == token::Comma { match self.token.kind {
seen_comma = true; token::Comma => {
self.bump();
} }
if self.eat(exp!(Semi)) { token::Semi => {
self.bump();
let sp = self.prev_token.span; let sp = self.prev_token.span;
let mut err = let mut err =
self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`")); self.dcx().struct_span_err(sp, format!("{adt_ty} fields are separated by `,`"));
@@ -1931,11 +1933,8 @@ impl<'a> Parser<'a> {
",", ",",
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
return Err(err); err.span_label(ident_span, format!("while parsing this {adt_ty}"));
} err.emit();
match self.token.kind {
token::Comma => {
self.bump();
} }
token::CloseBrace => {} token::CloseBrace => {}
token::DocComment(..) => { token::DocComment(..) => {
@@ -1945,19 +1944,11 @@ impl<'a> Parser<'a> {
missing_comma: None, missing_comma: None,
}; };
self.bump(); // consume the doc comment self.bump(); // consume the doc comment
let comma_after_doc_seen = self.eat(exp!(Comma)); if self.eat(exp!(Comma)) || self.token == token::CloseBrace {
// `seen_comma` is always false, because we are inside doc block
// condition is here to make code more readable
if !seen_comma && comma_after_doc_seen {
seen_comma = true;
}
if comma_after_doc_seen || self.token == token::CloseBrace {
self.dcx().emit_err(err); self.dcx().emit_err(err);
} else { } else {
if !seen_comma {
let sp = previous_span.shrink_to_hi(); let sp = previous_span.shrink_to_hi();
err.missing_comma = Some(sp); err.missing_comma = Some(sp);
}
return Err(self.dcx().create_err(err)); return Err(self.dcx().create_err(err));
} }
} }

View File

@@ -293,6 +293,7 @@ fn emit_malformed_attribute(
| sym::deprecated | sym::deprecated
| sym::optimize | sym::optimize
| sym::cold | sym::cold
| sym::must_use
) { ) {
return; return;
} }

View File

@@ -171,6 +171,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => { Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
self.check_may_dangle(hir_id, *attr_span) self.check_may_dangle(hir_id, *attr_span)
} }
Attribute::Parsed(AttributeKind::MustUse { span, .. }) => {
self.check_must_use(hir_id, *span, target)
}
Attribute::Unparsed(attr_item) => { Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style); style = Some(attr_item.style);
match attr.path().as_slice() { match attr.path().as_slice() {
@@ -245,7 +248,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr, span, target), | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr, span, target),
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
[sym::must_use, ..] => self.check_must_use(hir_id, attr, target),
[sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target), [sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target),
[sym::rustc_allow_incoherent_impl, ..] => { [sym::rustc_allow_incoherent_impl, ..] => {
self.check_allow_incoherent_impl(attr, span, target) self.check_allow_incoherent_impl(attr, span, target)
@@ -696,7 +698,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
AttributeKind::Deprecation { .. } AttributeKind::Deprecation { .. }
| AttributeKind::Repr { .. } | AttributeKind::Repr { .. }
| AttributeKind::Align { .. } | AttributeKind::Align { .. }
| AttributeKind::Cold(..), | AttributeKind::Cold(..)
| AttributeKind::MustUse { .. },
) => { ) => {
continue; continue;
} }
@@ -1576,7 +1579,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
} }
/// Warns against some misuses of `#[must_use]` /// Warns against some misuses of `#[must_use]`
fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) { fn check_must_use(&self, hir_id: HirId, attr_span: Span, target: Target) {
if matches!( if matches!(
target, target,
Target::Fn Target::Fn
@@ -1616,7 +1619,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
self.tcx.emit_node_span_lint( self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES, UNUSED_ATTRIBUTES,
hir_id, hir_id,
attr.span(), attr_span,
errors::MustUseNoEffect { article, target }, errors::MustUseNoEffect { article, target },
); );
} }

View File

@@ -20,6 +20,7 @@ macro_rules! impl_debug_strict_add {
($( $ty:ty )*) => { ($( $ty:ty )*) => {
$( $(
impl DebugStrictAdd for $ty { impl DebugStrictAdd for $ty {
#[inline]
fn debug_strict_add(self, other: Self) -> Self { fn debug_strict_add(self, other: Self) -> Self {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
self + other self + other
@@ -42,6 +43,7 @@ macro_rules! impl_debug_strict_sub {
($( $ty:ty )*) => { ($( $ty:ty )*) => {
$( $(
impl DebugStrictSub for $ty { impl DebugStrictSub for $ty {
#[inline]
fn debug_strict_sub(self, other: Self) -> Self { fn debug_strict_sub(self, other: Self) -> Self {
if cfg!(debug_assertions) { if cfg!(debug_assertions) {
self - other self - other

View File

@@ -89,10 +89,12 @@ impl FileEncoder {
self.buffered = 0; self.buffered = 0;
} }
#[inline]
pub fn file(&self) -> &File { pub fn file(&self) -> &File {
&self.file &self.file
} }
#[inline]
pub fn path(&self) -> &Path { pub fn path(&self) -> &Path {
&self.path &self.path
} }

View File

@@ -1213,6 +1213,17 @@ pub enum DesugaringKind {
Contract, Contract,
/// A pattern type range start/end /// A pattern type range start/end
PatTyRange, PatTyRange,
/// A format literal.
FormatLiteral {
/// Was this format literal written in the source?
/// - `format!("boo")` => Yes,
/// - `format!(concat!("b", "o", "o"))` => No,
/// - `format!(include_str!("boo.txt"))` => No,
///
/// If it wasn't written in the source then we have to be careful with suggestions about
/// rewriting it.
source: bool,
},
} }
impl DesugaringKind { impl DesugaringKind {
@@ -1231,6 +1242,10 @@ impl DesugaringKind {
DesugaringKind::BoundModifier => "trait bound modifier", DesugaringKind::BoundModifier => "trait bound modifier",
DesugaringKind::Contract => "contract check", DesugaringKind::Contract => "contract check",
DesugaringKind::PatTyRange => "pattern type", DesugaringKind::PatTyRange => "pattern type",
DesugaringKind::FormatLiteral { source: true } => "format string literal",
DesugaringKind::FormatLiteral { source: false } => {
"expression that expanded into a format string literal"
}
} }
} }
@@ -1250,6 +1265,7 @@ impl DesugaringKind {
DesugaringKind::BoundModifier => value == "BoundModifier", DesugaringKind::BoundModifier => value == "BoundModifier",
DesugaringKind::Contract => value == "Contract", DesugaringKind::Contract => value == "Contract",
DesugaringKind::PatTyRange => value == "PatTyRange", DesugaringKind::PatTyRange => value == "PatTyRange",
DesugaringKind::FormatLiteral { .. } => value == "FormatLiteral",
} }
} }
} }

View File

@@ -1080,7 +1080,6 @@ symbols! {
fs_create_dir, fs_create_dir,
fsub_algebraic, fsub_algebraic,
fsub_fast, fsub_fast,
fsxr,
full, full,
fundamental, fundamental,
fused_iterator, fused_iterator,
@@ -1088,6 +1087,7 @@ symbols! {
future_drop_poll, future_drop_poll,
future_output, future_output,
future_trait, future_trait,
fxsr,
gdb_script_file, gdb_script_file,
ge, ge,
gen_blocks, gen_blocks,

View File

@@ -2721,6 +2721,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
ObligationCauseCode::TupleElem => { ObligationCauseCode::TupleElem => {
err.note("only the last element of a tuple may have a dynamically sized type"); err.note("only the last element of a tuple may have a dynamically sized type");
} }
ObligationCauseCode::DynCompatible(span) => {
err.multipart_suggestion(
"you might have meant to use `Self` to refer to the implementing type",
vec![(span, "Self".into())],
Applicability::MachineApplicable,
);
}
ObligationCauseCode::WhereClause(item_def_id, span) ObligationCauseCode::WhereClause(item_def_id, span)
| ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..) | ObligationCauseCode::WhereClauseInExpr(item_def_id, span, ..)
| ObligationCauseCode::HostEffectInExpr(item_def_id, span, ..) | ObligationCauseCode::HostEffectInExpr(item_def_id, span, ..)
@@ -2872,6 +2879,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
_ => (), _ => (),
} }
} }
// If this is from a format string literal desugaring,
// we've already said "required by this formatting parameter"
let is_in_fmt_lit = if let Some(s) = err.span.primary_span() {
matches!(s.desugaring_kind(), Some(DesugaringKind::FormatLiteral { .. }))
} else {
false
};
if !is_in_fmt_lit {
let descr = format!("required by {a} bound in `{item_name}`"); let descr = format!("required by {a} bound in `{item_name}`");
if span.is_visible(sm) { if span.is_visible(sm) {
let msg = format!("required by {this} in `{short_item_name}`"); let msg = format!("required by {this} in `{short_item_name}`");
@@ -2880,6 +2896,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
} else { } else {
err.span_note(tcx.def_span(item_def_id), descr); err.span_note(tcx.def_span(item_def_id), descr);
} }
}
if let Some(note) = note { if let Some(note) = note {
err.note(note); err.note(note);
} }
@@ -3973,7 +3990,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
) = expr.kind ) = expr.kind
{ {
if Some(*span) != err.span.primary_span() { if Some(*span) != err.span.primary_span() {
err.span_label(*span, "required by a bound introduced by this call"); let msg = if span.is_desugaring(DesugaringKind::FormatLiteral { source: true })
{
"required by this formatting parameter"
} else if span.is_desugaring(DesugaringKind::FormatLiteral { source: false }) {
"required by a formatting parameter in this expression"
} else {
"required by a bound introduced by this call"
};
err.span_label(*span, msg);
} }
} }

View File

@@ -31,7 +31,7 @@ use crate::traits::{
/// ///
/// Currently that is `Self` in supertraits. This is needed /// Currently that is `Self` in supertraits. This is needed
/// because `dyn_compatibility_violations` can't be used during /// because `dyn_compatibility_violations` can't be used during
/// type collection. /// type collection, as type collection is needed for `dyn_compatiblity_violations` itself.
#[instrument(level = "debug", skip(tcx), ret)] #[instrument(level = "debug", skip(tcx), ret)]
pub fn hir_ty_lowering_dyn_compatibility_violations( pub fn hir_ty_lowering_dyn_compatibility_violations(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,

View File

@@ -855,11 +855,13 @@ impl Display for Arguments<'_> {
#[rustc_on_unimplemented( #[rustc_on_unimplemented(
on( on(
crate_local, crate_local,
label = "`{Self}` cannot be formatted using `{{:?}}`",
note = "add `#[derive(Debug)]` to `{Self}` or manually `impl {This} for {Self}`" note = "add `#[derive(Debug)]` to `{Self}` or manually `impl {This} for {Self}`"
), ),
message = "`{Self}` doesn't implement `{This}`", on(
from_desugaring = "FormatLiteral",
label = "`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{This}`" label = "`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{This}`"
),
message = "`{Self}` doesn't implement `{This}`"
)] )]
#[doc(alias = "{:?}")] #[doc(alias = "{:?}")]
#[rustc_diagnostic_item = "Debug"] #[rustc_diagnostic_item = "Debug"]
@@ -986,11 +988,14 @@ pub use macros::Debug;
any(Self = "std::path::Path", Self = "std::path::PathBuf"), any(Self = "std::path::Path", Self = "std::path::PathBuf"),
label = "`{Self}` cannot be formatted with the default formatter; call `.display()` on it", label = "`{Self}` cannot be formatted with the default formatter; call `.display()` on it",
note = "call `.display()` or `.to_string_lossy()` to safely print paths, \ note = "call `.display()` or `.to_string_lossy()` to safely print paths, \
as they may contain non-Unicode data" as they may contain non-Unicode data",
), ),
message = "`{Self}` doesn't implement `{This}`", on(
from_desugaring = "FormatLiteral",
note = "in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead",
label = "`{Self}` cannot be formatted with the default formatter", label = "`{Self}` cannot be formatted with the default formatter",
note = "in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead" ),
message = "`{Self}` doesn't implement `{This}`"
)] )]
#[doc(alias = "{}")] #[doc(alias = "{}")]
#[rustc_diagnostic_item = "Display"] #[rustc_diagnostic_item = "Display"]

View File

@@ -363,7 +363,14 @@ macro_rules! dbg {
match $val { match $val {
tmp => { tmp => {
$crate::eprintln!("[{}:{}:{}] {} = {:#?}", $crate::eprintln!("[{}:{}:{}] {} = {:#?}",
$crate::file!(), $crate::line!(), $crate::column!(), $crate::stringify!($val), &tmp); $crate::file!(),
$crate::line!(),
$crate::column!(),
$crate::stringify!($val),
// The `&T: Debug` check happens here (not in the format literal desugaring)
// to avoid format literal related messages and suggestions.
&&tmp as &dyn $crate::fmt::Debug,
);
tmp tmp
} }
} }

View File

@@ -531,7 +531,7 @@ enum EditorKind {
impl EditorKind { impl EditorKind {
// Used in `./tests.rs`. // Used in `./tests.rs`.
#[allow(dead_code)] #[cfg(test)]
pub const ALL: &[EditorKind] = &[ pub const ALL: &[EditorKind] = &[
EditorKind::Emacs, EditorKind::Emacs,
EditorKind::Helix, EditorKind::Helix,

View File

@@ -390,7 +390,6 @@ macro_rules! bootstrap_tool {
; ;
)+) => { )+) => {
#[derive(PartialEq, Eq, Clone)] #[derive(PartialEq, Eq, Clone)]
#[allow(dead_code)]
pub enum Tool { pub enum Tool {
$( $(
$name, $name,

View File

@@ -37,8 +37,8 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
// will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line // will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line
// are deliberately not in a doc comment, because they need not be in public docs.) // are deliberately not in a doc comment, because they need not be in public docs.)
// //
// Latest feature: improve handling of generic args // Latest feature: Pretty printing of must_use attributes changed
pub const FORMAT_VERSION: u32 = 51; pub const FORMAT_VERSION: u32 = 52;
/// The root of the emitted JSON blob. /// The root of the emitted JSON blob.
/// ///

View File

@@ -15,6 +15,9 @@ use clippy_utils::ty::is_must_use_ty;
use clippy_utils::visitors::for_each_expr_without_closures; use clippy_utils::visitors::for_each_expr_without_closures;
use clippy_utils::{return_ty, trait_ref_of_method}; use clippy_utils::{return_ty, trait_ref_of_method};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_attr_data_structures::AttributeKind;
use rustc_span::Symbol;
use rustc_attr_data_structures::find_attr;
use core::ops::ControlFlow; use core::ops::ControlFlow;
@@ -22,7 +25,7 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};
pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
let attrs = cx.tcx.hir_attrs(item.hir_id()); let attrs = cx.tcx.hir_attrs(item.hir_id());
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
if let hir::ItemKind::Fn { if let hir::ItemKind::Fn {
ref sig, ref sig,
body: ref body_id, body: ref body_id,
@@ -31,8 +34,8 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
{ {
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
if let Some(attr) = attr { if let Some((attr_span, reason)) = attr {
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, *attr_span, *reason, attrs, sig);
} else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) { } else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) {
check_must_use_candidate( check_must_use_candidate(
cx, cx,
@@ -52,9 +55,9 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
let attrs = cx.tcx.hir_attrs(item.hir_id()); let attrs = cx.tcx.hir_attrs(item.hir_id());
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
if let Some(attr) = attr { if let Some((attr_span, reason)) = attr {
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, *attr_span, *reason, attrs, sig);
} else if is_public && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id).is_none() { } else if is_public && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id).is_none() {
check_must_use_candidate( check_must_use_candidate(
cx, cx,
@@ -75,9 +78,9 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
let attrs = cx.tcx.hir_attrs(item.hir_id()); let attrs = cx.tcx.hir_attrs(item.hir_id());
let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); let attr = find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::MustUse { span, reason } => (span, reason));
if let Some(attr) = attr { if let Some((attr_span, reason)) = attr {
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig); check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, *attr_span, *reason, attrs, sig);
} else if let hir::TraitFn::Provided(eid) = *eid { } else if let hir::TraitFn::Provided(eid) = *eid {
let body = cx.tcx.hir_body(eid); let body = cx.tcx.hir_body(eid);
if attr.is_none() && is_public && !is_proc_macro(attrs) { if attr.is_none() && is_public && !is_proc_macro(attrs) {
@@ -103,7 +106,8 @@ fn check_needless_must_use(
item_id: hir::OwnerId, item_id: hir::OwnerId,
item_span: Span, item_span: Span,
fn_header_span: Span, fn_header_span: Span,
attr: &Attribute, attr_span: Span,
reason: Option<Symbol>,
attrs: &[Attribute], attrs: &[Attribute],
sig: &FnSig<'_>, sig: &FnSig<'_>,
) { ) {
@@ -119,7 +123,7 @@ fn check_needless_must_use(
"this unit-returning function has a `#[must_use]` attribute", "this unit-returning function has a `#[must_use]` attribute",
|diag| { |diag| {
diag.span_suggestion( diag.span_suggestion(
attr.span(), attr_span,
"remove the attribute", "remove the attribute",
"", "",
Applicability::MachineApplicable, Applicability::MachineApplicable,
@@ -137,11 +141,11 @@ fn check_needless_must_use(
MUST_USE_UNIT, MUST_USE_UNIT,
fn_header_span, fn_header_span,
"this unit-returning function has a `#[must_use]` attribute", "this unit-returning function has a `#[must_use]` attribute",
Some(attr.span()), Some(attr_span),
"remove `must_use`", "remove `must_use`",
); );
} }
} else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) { } else if reason.is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
// Ignore async functions unless Future::Output type is a must_use type // Ignore async functions unless Future::Output type is a must_use type
if sig.header.is_async() { if sig.header.is_async() {
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());

View File

@@ -6,7 +6,9 @@ use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind}; use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind};
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
use rustc_span::{Span, sym}; use rustc_span::{Span};
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::find_attr;
declare_clippy_lint! { declare_clippy_lint! {
/// ### What it does /// ### What it does
@@ -74,7 +76,10 @@ fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, spa
// We only show this warning for public exported methods. // We only show this warning for public exported methods.
&& cx.effective_visibilities.is_exported(fn_def) && cx.effective_visibilities.is_exported(fn_def)
// We don't want to emit this lint if the `#[must_use]` attribute is already there. // We don't want to emit this lint if the `#[must_use]` attribute is already there.
&& !cx.tcx.hir_attrs(owner_id.into()).iter().any(|attr| attr.has_name(sym::must_use)) && !find_attr!(
cx.tcx.hir_attrs(owner_id.into()),
AttributeKind::MustUse { .. }
)
&& cx.tcx.visibility(fn_def.to_def_id()).is_public() && cx.tcx.visibility(fn_def.to_def_id()).is_public()
&& let ret_ty = return_ty(cx, owner_id) && let ret_ty = return_ty(cx, owner_id)
&& let self_arg = nth_arg(cx, owner_id, 0) && let self_arg = nth_arg(cx, owner_id, 0)

View File

@@ -1886,7 +1886,10 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
_ => None, _ => None,
}; };
did.is_some_and(|did| cx.tcx.has_attr(did, sym::must_use)) did.is_some_and(|did| find_attr!(
cx.tcx.get_all_attrs(did),
AttributeKind::MustUse { ..}
))
} }
/// Checks if a function's body represents the identity function. Looks for bodies of the form: /// Checks if a function's body represents the identity function. Looks for bodies of the form:

View File

@@ -31,6 +31,8 @@ use rustc_trait_selection::traits::{Obligation, ObligationCause};
use std::assert_matches::debug_assert_matches; use std::assert_matches::debug_assert_matches;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::iter; use std::iter;
use rustc_attr_data_structures::find_attr;
use rustc_attr_data_structures::AttributeKind;
use crate::path_res; use crate::path_res;
use crate::paths::{PathNS, lookup_path_str}; use crate::paths::{PathNS, lookup_path_str};
@@ -326,8 +328,14 @@ pub fn has_drop<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
// Returns whether the type has #[must_use] attribute // Returns whether the type has #[must_use] attribute
pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
match ty.kind() { match ty.kind() {
ty::Adt(adt, _) => cx.tcx.has_attr(adt.did(), sym::must_use), ty::Adt(adt, _) => find_attr!(
ty::Foreign(did) => cx.tcx.has_attr(*did, sym::must_use), cx.tcx.get_all_attrs(adt.did()),
AttributeKind::MustUse { ..}
),
ty::Foreign(did) => find_attr!(
cx.tcx.get_all_attrs(*did),
AttributeKind::MustUse { ..}
),
ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => { ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => {
// for the Array case we don't need to care for the len == 0 case // for the Array case we don't need to care for the len == 0 case
// because we don't want to lint functions returning empty arrays // because we don't want to lint functions returning empty arrays
@@ -337,7 +345,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => { ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {
for (predicate, _) in cx.tcx.explicit_item_self_bounds(def_id).skip_binder() { for (predicate, _) in cx.tcx.explicit_item_self_bounds(def_id).skip_binder() {
if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
&& cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) && find_attr!(cx.tcx.get_all_attrs(trait_predicate.trait_ref.def_id), AttributeKind::MustUse { ..})
{ {
return true; return true;
} }
@@ -347,7 +355,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
ty::Dynamic(binder, _, _) => { ty::Dynamic(binder, _, _) => {
for predicate in *binder { for predicate in *binder {
if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder()
&& cx.tcx.has_attr(trait_ref.def_id, sym::must_use) && find_attr!(cx.tcx.get_all_attrs(trait_ref.def_id), AttributeKind::MustUse { ..})
{ {
return true; return true;
} }

View File

@@ -62,6 +62,9 @@ pub fn check(librustdoc_path: &Path, tools_path: &Path, src_path: &Path, bad: &m
return; return;
} }
}; };
// Having the correct `eslint` version installed via `npm` isn't strictly necessary, since we're invoking it via `npx`,
// but this check allows the vast majority that is not working on the rustdoc frontend to avoid the penalty of running
// `eslint` in tidy. See also: https://github.com/rust-lang/rust/pull/142851
match get_eslint_version() { match get_eslint_version() {
Some(version) => { Some(version) => {
if version != eslint_version { if version != eslint_version {

View File

@@ -1,9 +1,9 @@
#![no_std] #![no_std]
//@ is "$.index[?(@.name=='example')].attrs" '["#[must_use]"]' //@ is "$.index[?(@.name=='example')].attrs" '["#[attr = MustUse]"]'
#[must_use] #[must_use]
pub fn example() -> impl Iterator<Item = i64> {} pub fn example() -> impl Iterator<Item = i64> {}
//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]"]' //@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[attr = MustUse {reason: \"does nothing if you do not use it\"}]"]'
#[must_use = "does nothing if you do not use it"] #[must_use = "does nothing if you do not use it"]
pub fn explicit_message() -> impl Iterator<Item = i64> {} pub fn explicit_message() -> impl Iterator<Item = i64> {}

View File

@@ -17,10 +17,8 @@ error[E0277]: `()` doesn't implement `std::fmt::Display`
--> $DIR/issue-100154.rs:4:11 --> $DIR/issue-100154.rs:4:11
| |
LL | foo::<()>(()); LL | foo::<()>(());
| ^^ `()` cannot be formatted with the default formatter | ^^ the trait `std::fmt::Display` is not implemented for `()`
| |
= help: the trait `std::fmt::Display` is not implemented for `()`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `foo` note: required by a bound in `foo`
--> $DIR/issue-100154.rs:1:16 --> $DIR/issue-100154.rs:1:16
| |

View File

@@ -2,9 +2,8 @@ error[E0277]: `Self` doesn't implement `std::fmt::Display`
--> $DIR/defaults-unsound-62211-1.rs:24:96 --> $DIR/defaults-unsound-62211-1.rs:24:96
| |
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self; LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ `Self` cannot be formatted with the default formatter | ^^^^ the trait `std::fmt::Display` is not implemented for `Self`
| |
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `UncheckedCopy::Output` note: required by a bound in `UncheckedCopy::Output`
--> $DIR/defaults-unsound-62211-1.rs:24:86 --> $DIR/defaults-unsound-62211-1.rs:24:86
| |

View File

@@ -2,9 +2,8 @@ error[E0277]: `Self` doesn't implement `std::fmt::Display`
--> $DIR/defaults-unsound-62211-1.rs:24:96 --> $DIR/defaults-unsound-62211-1.rs:24:96
| |
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self; LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ `Self` cannot be formatted with the default formatter | ^^^^ the trait `std::fmt::Display` is not implemented for `Self`
| |
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `UncheckedCopy::Output` note: required by a bound in `UncheckedCopy::Output`
--> $DIR/defaults-unsound-62211-1.rs:24:86 --> $DIR/defaults-unsound-62211-1.rs:24:86
| |

View File

@@ -2,9 +2,8 @@ error[E0277]: `Self` doesn't implement `std::fmt::Display`
--> $DIR/defaults-unsound-62211-2.rs:24:96 --> $DIR/defaults-unsound-62211-2.rs:24:96
| |
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self; LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ `Self` cannot be formatted with the default formatter | ^^^^ the trait `std::fmt::Display` is not implemented for `Self`
| |
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `UncheckedCopy::Output` note: required by a bound in `UncheckedCopy::Output`
--> $DIR/defaults-unsound-62211-2.rs:24:86 --> $DIR/defaults-unsound-62211-2.rs:24:86
| |

View File

@@ -2,9 +2,8 @@ error[E0277]: `Self` doesn't implement `std::fmt::Display`
--> $DIR/defaults-unsound-62211-2.rs:24:96 --> $DIR/defaults-unsound-62211-2.rs:24:96
| |
LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self; LL | type Output: Copy + Deref<Target = str> + AddAssign<&'static str> + From<Self> + Display = Self;
| ^^^^ `Self` cannot be formatted with the default formatter | ^^^^ the trait `std::fmt::Display` is not implemented for `Self`
| |
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `UncheckedCopy::Output` note: required by a bound in `UncheckedCopy::Output`
--> $DIR/defaults-unsound-62211-2.rs:24:86 --> $DIR/defaults-unsound-62211-2.rs:24:86
| |

View File

@@ -0,0 +1,4 @@
#[must_use()] //~ ERROR valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]`
struct Test;
fn main() {}

View File

@@ -0,0 +1,8 @@
error: valid forms for the attribute are `#[must_use = "reason"]` and `#[must_use]`
--> $DIR/malformed-must_use.rs:1:1
|
LL | #[must_use()]
| ^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@@ -16,9 +16,8 @@ LL | fn foo(s: &i32) -> &i32 {
| --- consider calling this function | --- consider calling this function
... ...
LL | assert_eq!(foo, y); LL | assert_eq!(foo, y);
| ^^^^^^^^^^^^^^^^^^ `for<'a> fn(&'a i32) -> &'a i32 {foo}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `for<'a> fn(&'a i32) -> &'a i32 {foo}`
| |
= help: the trait `Debug` is not implemented for fn item `for<'a> fn(&'a i32) -> &'a i32 {foo}`
= help: use parentheses to call this function: `foo(/* &i32 */)` = help: use parentheses to call this function: `foo(/* &i32 */)`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -14,11 +14,9 @@ error[E0277]: the size for values of type `dyn Foo` cannot be known at compilati
LL | println!("{:?}", foo); LL | println!("{:?}", foo);
| ---- ^^^ doesn't have a size known at compile-time | ---- ^^^ doesn't have a size known at compile-time
| | | |
| required by a bound introduced by this call | required by this formatting parameter
| |
= help: the trait `Sized` is not implemented for `dyn Foo` = help: the trait `Sized` is not implemented for `dyn Foo`
note: required by an implicit `Sized` bound in `core::fmt::rt::Argument::<'_>::new_debug`
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@@ -13,7 +13,7 @@ LL | println!("{:?}", 0);
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
| |
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0015]: cannot call non-const function `_print` in constant functions error[E0015]: cannot call non-const function `_print` in constant functions
--> $DIR/format.rs:7:5 --> $DIR/format.rs:7:5

View File

@@ -5,9 +5,8 @@ LL | #[derive(Debug)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
... ...
LL | x: Error LL | x: Error
| ^^^^^^^^ `Error` cannot be formatted using `{:?}` | ^^^^^^^^ the trait `Debug` is not implemented for `Error`
| |
= help: the trait `Debug` is not implemented for `Error`
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error` = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
help: consider annotating `Error` with `#[derive(Debug)]` help: consider annotating `Error` with `#[derive(Debug)]`
| |

View File

@@ -5,9 +5,8 @@ LL | #[derive(Debug)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
... ...
LL | Error LL | Error
| ^^^^^ `Error` cannot be formatted using `{:?}` | ^^^^^ the trait `Debug` is not implemented for `Error`
| |
= help: the trait `Debug` is not implemented for `Error`
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error` = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
help: consider annotating `Error` with `#[derive(Debug)]` help: consider annotating `Error` with `#[derive(Debug)]`
| |

View File

@@ -5,9 +5,8 @@ LL | #[derive(Debug)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
LL | struct Struct { LL | struct Struct {
LL | x: Error LL | x: Error
| ^^^^^^^^ `Error` cannot be formatted using `{:?}` | ^^^^^^^^ the trait `Debug` is not implemented for `Error`
| |
= help: the trait `Debug` is not implemented for `Error`
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error` = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
help: consider annotating `Error` with `#[derive(Debug)]` help: consider annotating `Error` with `#[derive(Debug)]`
| |

View File

@@ -5,9 +5,8 @@ LL | #[derive(Debug)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
LL | struct Struct( LL | struct Struct(
LL | Error LL | Error
| ^^^^^ `Error` cannot be formatted using `{:?}` | ^^^^^ the trait `Debug` is not implemented for `Error`
| |
= help: the trait `Debug` is not implemented for `Error`
= note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error` = note: add `#[derive(Debug)]` to `Error` or manually `impl Debug for Error`
help: consider annotating `Error` with `#[derive(Debug)]` help: consider annotating `Error` with `#[derive(Debug)]`
| |

View File

@@ -87,6 +87,11 @@ help: alternatively, consider constraining `g` so it does not apply to trait obj
| |
LL | trait A { fn g(b: B) -> B where Self: Sized; } LL | trait A { fn g(b: B) -> B where Self: Sized; }
| +++++++++++++++++ | +++++++++++++++++
help: you might have meant to use `Self` to refer to the implementing type
|
LL - trait B { fn f(a: A) -> A; }
LL + trait B { fn f(a: Self) -> A; }
|
warning: trait objects without an explicit `dyn` are deprecated warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/avoid-ice-on-warning-3.rs:14:19 --> $DIR/avoid-ice-on-warning-3.rs:14:19
@@ -124,6 +129,11 @@ help: alternatively, consider constraining `f` so it does not apply to trait obj
| |
LL | trait B { fn f(a: A) -> A where Self: Sized; } LL | trait B { fn f(a: A) -> A where Self: Sized; }
| +++++++++++++++++ | +++++++++++++++++
help: you might have meant to use `Self` to refer to the implementing type
|
LL - trait A { fn g(b: B) -> B; }
LL + trait A { fn g(b: Self) -> B; }
|
error: aborting due to 2 previous errors; 6 warnings emitted error: aborting due to 2 previous errors; 6 warnings emitted

View File

@@ -8,8 +8,7 @@ trait GatTrait {
trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> { trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> {
fn c(&self) -> dyn SuperTrait<T>; fn c(&self) -> dyn SuperTrait<T>;
//~^ ERROR associated item referring to unboxed trait object for its own trait //~^ ERROR the trait `SuperTrait` is not dyn compatible
//~| ERROR the trait `SuperTrait` is not dyn compatible
} }
fn main() {} fn main() {}

View File

@@ -7,20 +7,6 @@ LL | Self: 'a;
| ^^ | ^^
= help: consider adding an explicit lifetime bound `Self: 'a`... = help: consider adding an explicit lifetime bound `Self: 'a`...
error: associated item referring to unboxed trait object for its own trait
--> $DIR/supertrait-mentions-GAT.rs:10:20
|
LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> {
| ---------- in this trait
LL | fn c(&self) -> dyn SuperTrait<T>;
| ^^^^^^^^^^^^^^^^^
|
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn c(&self) -> dyn SuperTrait<T>;
LL + fn c(&self) -> Self;
|
error[E0038]: the trait `SuperTrait` is not dyn compatible error[E0038]: the trait `SuperTrait` is not dyn compatible
--> $DIR/supertrait-mentions-GAT.rs:10:20 --> $DIR/supertrait-mentions-GAT.rs:10:20
| |
@@ -37,8 +23,13 @@ LL | type Gat<'a>
LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> { LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> {
| ---------- this trait is not dyn compatible... | ---------- this trait is not dyn compatible...
= help: consider moving `Gat` to another trait = help: consider moving `Gat` to another trait
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn c(&self) -> dyn SuperTrait<T>;
LL + fn c(&self) -> Self;
|
error: aborting due to 3 previous errors error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0311. Some errors have detailed explanations: E0038, E0311.
For more information about an error, try `rustc --explain E0038`. For more information about an error, try `rustc --explain E0038`.

View File

@@ -2,10 +2,8 @@ error[E0277]: `A` doesn't implement `std::fmt::Display`
--> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL --> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL
| |
LL | impl r#trait::Trait for A {} LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter | ^ the trait `std::fmt::Display` is not implemented for `A`
| |
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait` note: required by a bound in `Trait`
--> $DIR/auxiliary/trait.rs:LL:COL --> $DIR/auxiliary/trait.rs:LL:COL
| |

View File

@@ -2,10 +2,8 @@ error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
| |
LL | impl r#trait::Trait for A {} LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter | ^ the trait `std::fmt::Display` is not implemented for `A`
| |
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait` note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-debuginfo.rs:LL:COL --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
| |

View File

@@ -2,10 +2,8 @@ error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
| |
LL | impl r#trait::Trait for A {} LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter | ^ the trait `std::fmt::Display` is not implemented for `A`
| |
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait` note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-diag.rs:LL:COL --> $DIR/auxiliary/trait-diag.rs:LL:COL
| |

View File

@@ -2,10 +2,8 @@ error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
| |
LL | impl r#trait::Trait for A {} LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter | ^ the trait `std::fmt::Display` is not implemented for `A`
| |
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait` note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-macro.rs:LL:COL --> $DIR/auxiliary/trait-macro.rs:LL:COL
| |

View File

@@ -2,10 +2,8 @@ error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
| |
LL | impl r#trait::Trait for A {} LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter | ^ the trait `std::fmt::Display` is not implemented for `A`
| |
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait` note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-debuginfo.rs:LL:COL --> $DIR/auxiliary/trait-debuginfo.rs:LL:COL
| |

View File

@@ -2,10 +2,8 @@ error[E0277]: `A` doesn't implement `std::fmt::Display`
--> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL --> remapped/errors/remap-path-prefix-diagnostics.rs:LL:COL
| |
LL | impl r#trait::Trait for A {} LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter | ^ the trait `std::fmt::Display` is not implemented for `A`
| |
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait` note: required by a bound in `Trait`
--> remapped/errors/auxiliary/trait-diag.rs:LL:COL --> remapped/errors/auxiliary/trait-diag.rs:LL:COL
| |

View File

@@ -2,10 +2,8 @@ error[E0277]: `A` doesn't implement `std::fmt::Display`
--> $DIR/remap-path-prefix-diagnostics.rs:LL:COL --> $DIR/remap-path-prefix-diagnostics.rs:LL:COL
| |
LL | impl r#trait::Trait for A {} LL | impl r#trait::Trait for A {}
| ^ `A` cannot be formatted with the default formatter | ^ the trait `std::fmt::Display` is not implemented for `A`
| |
= help: the trait `std::fmt::Display` is not implemented for `A`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Trait` note: required by a bound in `Trait`
--> $DIR/auxiliary/trait-macro.rs:LL:COL --> $DIR/auxiliary/trait-macro.rs:LL:COL
| |

View File

@@ -403,12 +403,6 @@ LL | #![link_section = "1800"]
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: `#[must_use]` has no effect when applied to a module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
|
LL | #![must_use]
| ^^^^^^^^^^^^
warning: attribute should be applied to a function definition warning: attribute should be applied to a function definition
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:62:1
| |
@@ -417,6 +411,12 @@ LL | #![cold]
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
warning: `#[must_use]` has no effect when applied to a module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:72:1
|
LL | #![must_use]
| ^^^^^^^^^^^^
warning: `#[macro_use]` only has an effect on `extern crate` and modules warning: `#[macro_use]` only has an effect on `extern crate` and modules
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:5 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:5
| |

View File

@@ -12,7 +12,9 @@ error[E0277]: `Option<{integer}>` doesn't implement `std::fmt::Display`
--> $DIR/format-args-argument-span.rs:15:37 --> $DIR/format-args-argument-span.rs:15:37
| |
LL | println!("{x:?} {x} {x:?}", x = Some(1)); LL | println!("{x:?} {x} {x:?}", x = Some(1));
| ^^^^^^^ `Option<{integer}>` cannot be formatted with the default formatter | --- ^^^^^^^ `Option<{integer}>` cannot be formatted with the default formatter
| |
| required by this formatting parameter
| |
= help: the trait `std::fmt::Display` is not implemented for `Option<{integer}>` = help: the trait `std::fmt::Display` is not implemented for `Option<{integer}>`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
@@ -22,7 +24,7 @@ error[E0277]: `DisplayOnly` doesn't implement `Debug`
--> $DIR/format-args-argument-span.rs:18:19 --> $DIR/format-args-argument-span.rs:18:19
| |
LL | println!("{x} {x:?} {x}"); LL | println!("{x} {x:?} {x}");
| ^^^^^ `DisplayOnly` cannot be formatted using `{:?}` | ^^^^^ `DisplayOnly` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
= help: the trait `Debug` is not implemented for `DisplayOnly` = help: the trait `Debug` is not implemented for `DisplayOnly`
= note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly`
@@ -37,7 +39,9 @@ error[E0277]: `DisplayOnly` doesn't implement `Debug`
--> $DIR/format-args-argument-span.rs:20:35 --> $DIR/format-args-argument-span.rs:20:35
| |
LL | println!("{x} {x:?} {x}", x = DisplayOnly); LL | println!("{x} {x:?} {x}", x = DisplayOnly);
| ^^^^^^^^^^^ `DisplayOnly` cannot be formatted using `{:?}` | ----- ^^^^^^^^^^^ `DisplayOnly` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= help: the trait `Debug` is not implemented for `DisplayOnly` = help: the trait `Debug` is not implemented for `DisplayOnly`
= note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly`

View File

@@ -4,7 +4,7 @@ error[E0277]: the trait bound `str: UpperHex` is not satisfied
LL | format!("{:X}", "3"); LL | format!("{:X}", "3");
| ---- ^^^ the trait `UpperHex` is not implemented for `str` | ---- ^^^ the trait `UpperHex` is not implemented for `str`
| | | |
| required by a bound introduced by this call | required by this formatting parameter
| |
= help: the following other types implement trait `UpperHex`: = help: the following other types implement trait `UpperHex`:
&T &T
@@ -17,8 +17,6 @@ LL | format!("{:X}", "3");
i32 i32
and 9 others and 9 others
= note: required for `&str` to implement `UpperHex` = note: required for `&str` to implement `UpperHex`
note: required by a bound in `core::fmt::rt::Argument::<'_>::new_upper_hex`
--> $SRC_DIR/core/src/fmt/rt.rs:LL:COL
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@@ -0,0 +1,13 @@
/// Do not point at the format string if it wasn't written in the source.
//@ forbid-output: required by this formatting parameter
#[derive(Debug)]
pub struct NonDisplay;
pub struct NonDebug;
fn main() {
let _ = format!(concat!("{", "}"), NonDisplay); //~ ERROR
let _ = format!(concat!("{", "0", "}"), NonDisplay); //~ ERROR
let _ = format!(concat!("{:", "?}"), NonDebug); //~ ERROR
let _ = format!(concat!("{", "0", ":?}"), NonDebug); //~ ERROR
}

View File

@@ -0,0 +1,53 @@
error[E0277]: `NonDisplay` doesn't implement `std::fmt::Display`
--> $DIR/non-source-literals.rs:9:40
|
LL | let _ = format!(concat!("{", "}"), NonDisplay);
| ^^^^^^^^^^ `NonDisplay` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `NonDisplay`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `NonDisplay` doesn't implement `std::fmt::Display`
--> $DIR/non-source-literals.rs:10:45
|
LL | let _ = format!(concat!("{", "0", "}"), NonDisplay);
| ^^^^^^^^^^ `NonDisplay` cannot be formatted with the default formatter
|
= help: the trait `std::fmt::Display` is not implemented for `NonDisplay`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `NonDebug` doesn't implement `Debug`
--> $DIR/non-source-literals.rs:11:42
|
LL | let _ = format!(concat!("{:", "?}"), NonDebug);
| ^^^^^^^^ `NonDebug` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= help: the trait `Debug` is not implemented for `NonDebug`
= note: add `#[derive(Debug)]` to `NonDebug` or manually `impl Debug for NonDebug`
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `NonDebug` with `#[derive(Debug)]`
|
LL + #[derive(Debug)]
LL | pub struct NonDebug;
|
error[E0277]: `NonDebug` doesn't implement `Debug`
--> $DIR/non-source-literals.rs:12:47
|
LL | let _ = format!(concat!("{", "0", ":?}"), NonDebug);
| ^^^^^^^^ `NonDebug` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= help: the trait `Debug` is not implemented for `NonDebug`
= note: add `#[derive(Debug)]` to `NonDebug` or manually `impl Debug for NonDebug`
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `NonDebug` with `#[derive(Debug)]`
|
LL + #[derive(Debug)]
LL | pub struct NonDebug;
|
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@@ -2,9 +2,8 @@ error[E0277]: `T` doesn't implement `std::fmt::Display`
--> $DIR/generic-associated-types-where.rs:18:22 --> $DIR/generic-associated-types-where.rs:18:22
| |
LL | type Assoc2<T> = Vec<T>; LL | type Assoc2<T> = Vec<T>;
| ^^^^^^ `T` cannot be formatted with the default formatter | ^^^^^^ the trait `std::fmt::Display` is not implemented for `T`
| |
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
help: consider restricting type parameter `T` with trait `Display` help: consider restricting type parameter `T` with trait `Display`
| |
LL | type Assoc2<T: std::fmt::Display> = Vec<T>; LL | type Assoc2<T: std::fmt::Display> = Vec<T>;

View File

@@ -2,10 +2,8 @@ error[E0277]: `()` doesn't implement `std::fmt::Display`
--> $DIR/doesnt-satisfy.rs:6:17 --> $DIR/doesnt-satisfy.rs:6:17
| |
LL | fn bar() -> () {} LL | fn bar() -> () {}
| ^^ `()` cannot be formatted with the default formatter | ^^ the trait `std::fmt::Display` is not implemented for `()`
| |
= help: the trait `std::fmt::Display` is not implemented for `()`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `Foo::bar::{anon_assoc#0}` note: required by a bound in `Foo::bar::{anon_assoc#0}`
--> $DIR/doesnt-satisfy.rs:2:22 --> $DIR/doesnt-satisfy.rs:2:22
| |

View File

@@ -39,9 +39,8 @@ error[E0277]: `T` doesn't implement `std::fmt::Display`
--> $DIR/wf-bounds.rs:21:26 --> $DIR/wf-bounds.rs:21:26
| |
LL | fn nya4<T>() -> impl Wf<NeedsDisplay<T>>; LL | fn nya4<T>() -> impl Wf<NeedsDisplay<T>>;
| ^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter | ^^^^^^^^^^^^^^^^^^^ the trait `std::fmt::Display` is not implemented for `T`
| |
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `NeedsDisplay` note: required by a bound in `NeedsDisplay`
--> $DIR/wf-bounds.rs:9:24 --> $DIR/wf-bounds.rs:9:24
| |

View File

@@ -87,18 +87,16 @@ error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug`
--> $DIR/issue-59488.rs:30:5 --> $DIR/issue-59488.rs:30:5
| |
LL | assert_eq!(Foo::Bar, i); LL | assert_eq!(Foo::Bar, i);
| ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}`
| |
= help: the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug`
--> $DIR/issue-59488.rs:30:5 --> $DIR/issue-59488.rs:30:5
| |
LL | assert_eq!(Foo::Bar, i); LL | assert_eq!(Foo::Bar, i);
| ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}`
| |
= help: the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 10 previous errors error: aborting due to 10 previous errors

View File

@@ -26,9 +26,8 @@ LL | fn a() -> i32 {
| - consider calling this function | - consider calling this function
... ...
LL | assert_eq!(a, 0); LL | assert_eq!(a, 0);
| ^^^^^^^^^^^^^^^^ `fn() -> i32 {a}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for fn item `fn() -> i32 {a}`
| |
= help: the trait `Debug` is not implemented for fn item `fn() -> i32 {a}`
= help: use parentheses to call this function: `a()` = help: use parentheses to call this function: `a()`
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -65,19 +65,6 @@ LL | #[should_panic]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:60:1
|
LL | #[must_use = "some message"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/unused-attr-duplicate.rs:59:1
|
LL | #[must_use]
| ^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
error: unused attribute error: unused attribute
--> $DIR/unused-attr-duplicate.rs:66:1 --> $DIR/unused-attr-duplicate.rs:66:1
| |
@@ -264,6 +251,19 @@ note: attribute also specified here
LL | #[macro_export] LL | #[macro_export]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:60:1
|
LL | #[must_use = "some message"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/unused-attr-duplicate.rs:59:1
|
LL | #[must_use]
| ^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
error: unused attribute error: unused attribute
--> $DIR/unused-attr-duplicate.rs:74:1 --> $DIR/unused-attr-duplicate.rs:74:1
| |

View File

@@ -2,7 +2,7 @@ error[E0599]: `*const u8` doesn't implement `std::fmt::Display`
--> $DIR/suggest-convert-ptr-to-ref.rs:5:22 --> $DIR/suggest-convert-ptr-to-ref.rs:5:22
| |
LL | println!("{}", z.to_string()); LL | println!("{}", z.to_string());
| ^^^^^^^^^ `*const u8` cannot be formatted with the default formatter | ^^^^^^^^^ method cannot be called on `*const u8` due to unsatisfied trait bounds
| |
note: the method `to_string` exists on the type `&u8` note: the method `to_string` exists on the type `&u8`
--> $SRC_DIR/alloc/src/string.rs:LL:COL --> $SRC_DIR/alloc/src/string.rs:LL:COL
@@ -11,13 +11,12 @@ note: the method `to_string` exists on the type `&u8`
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`*const u8: std::fmt::Display` `*const u8: std::fmt::Display`
which is required by `*const u8: ToString` which is required by `*const u8: ToString`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
error[E0599]: `*mut u8` doesn't implement `std::fmt::Display` error[E0599]: `*mut u8` doesn't implement `std::fmt::Display`
--> $DIR/suggest-convert-ptr-to-ref.rs:8:22 --> $DIR/suggest-convert-ptr-to-ref.rs:8:22
| |
LL | println!("{}", t.to_string()); LL | println!("{}", t.to_string());
| ^^^^^^^^^ `*mut u8` cannot be formatted with the default formatter | ^^^^^^^^^ method cannot be called on `*mut u8` due to unsatisfied trait bounds
| |
note: the method `to_string` exists on the type `&&mut u8` note: the method `to_string` exists on the type `&&mut u8`
--> $SRC_DIR/alloc/src/string.rs:LL:COL --> $SRC_DIR/alloc/src/string.rs:LL:COL
@@ -26,7 +25,6 @@ note: the method `to_string` exists on the type `&&mut u8`
= note: the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`*mut u8: std::fmt::Display` `*mut u8: std::fmt::Display`
which is required by `*mut u8: ToString` which is required by `*mut u8: ToString`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
error[E0599]: no method named `make_ascii_lowercase` found for raw pointer `*mut u8` in the current scope error[E0599]: no method named `make_ascii_lowercase` found for raw pointer `*mut u8` in the current scope
--> $DIR/suggest-convert-ptr-to-ref.rs:9:7 --> $DIR/suggest-convert-ptr-to-ref.rs:9:7

View File

@@ -2,9 +2,8 @@ error[E0277]: `Foo` doesn't implement `Debug`
--> $DIR/method-help-unsatisfied-bound.rs:5:7 --> $DIR/method-help-unsatisfied-bound.rs:5:7
| |
LL | a.unwrap(); LL | a.unwrap();
| ^^^^^^ `Foo` cannot be formatted using `{:?}` | ^^^^^^ the trait `Debug` is not implemented for `Foo`
| |
= help: the trait `Debug` is not implemented for `Foo`
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
note: required by a bound in `Result::<T, E>::unwrap` note: required by a bound in `Result::<T, E>::unwrap`
--> $SRC_DIR/core/src/result.rs:LL:COL --> $SRC_DIR/core/src/result.rs:LL:COL

View File

@@ -2,11 +2,10 @@ error[E0277]: `Dummy` doesn't implement `Debug`
--> $DIR/issue-107649.rs:105:5 --> $DIR/issue-107649.rs:105:5
| |
105 | dbg!(lib::Dummy); 105 | dbg!(lib::Dummy);
| ^^^^^^^^^^^^^^^^ `Dummy` cannot be formatted using `{:?}` | ^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `Dummy`
| |
= help: the trait `Debug` is not implemented for `Dummy`
= note: add `#[derive(Debug)]` to `Dummy` or manually `impl Debug for Dummy` = note: add `#[derive(Debug)]` to `Dummy` or manually `impl Debug for Dummy`
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Dummy` with `#[derive(Debug)]` help: consider annotating `Dummy` with `#[derive(Debug)]`
--> $DIR/auxiliary/dummy_lib.rs:2:1 --> $DIR/auxiliary/dummy_lib.rs:2:1
| |

View File

@@ -2,7 +2,9 @@ error[E0277]: `Foo` doesn't implement `Debug`
--> $DIR/no-debug.rs:10:27 --> $DIR/no-debug.rs:10:27
| |
LL | println!("{:?} {:?}", Foo, Bar); LL | println!("{:?} {:?}", Foo, Bar);
| ^^^ `Foo` cannot be formatted using `{:?}` | ---- ^^^ `Foo` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= help: the trait `Debug` is not implemented for `Foo` = help: the trait `Debug` is not implemented for `Foo`
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo` = note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
@@ -17,7 +19,9 @@ error[E0277]: `Bar` doesn't implement `Debug`
--> $DIR/no-debug.rs:10:32 --> $DIR/no-debug.rs:10:32
| |
LL | println!("{:?} {:?}", Foo, Bar); LL | println!("{:?} {:?}", Foo, Bar);
| ^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ---- ^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= help: the trait `Debug` is not implemented for `Bar` = help: the trait `Debug` is not implemented for `Bar`
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -26,7 +30,9 @@ error[E0277]: `Foo` doesn't implement `std::fmt::Display`
--> $DIR/no-debug.rs:11:23 --> $DIR/no-debug.rs:11:23
| |
LL | println!("{} {}", Foo, Bar); LL | println!("{} {}", Foo, Bar);
| ^^^ `Foo` cannot be formatted with the default formatter | -- ^^^ `Foo` cannot be formatted with the default formatter
| |
| required by this formatting parameter
| |
= help: the trait `std::fmt::Display` is not implemented for `Foo` = help: the trait `std::fmt::Display` is not implemented for `Foo`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
@@ -36,7 +42,9 @@ error[E0277]: `Bar` doesn't implement `std::fmt::Display`
--> $DIR/no-debug.rs:11:28 --> $DIR/no-debug.rs:11:28
| |
LL | println!("{} {}", Foo, Bar); LL | println!("{} {}", Foo, Bar);
| ^^^ `Bar` cannot be formatted with the default formatter | -- ^^^ `Bar` cannot be formatted with the default formatter
| |
| required by this formatting parameter
| |
= help: the trait `std::fmt::Display` is not implemented for `Bar` = help: the trait `std::fmt::Display` is not implemented for `Bar`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead

View File

@@ -33,7 +33,6 @@ fn f() {}
#[must_use = "string"suffix] #[must_use = "string"suffix]
//~^ ERROR suffixes on string literals are invalid //~^ ERROR suffixes on string literals are invalid
//~| ERROR malformed `must_use` attribute input
fn g() {} fn g() {}
#[link(name = "string"suffix)] #[link(name = "string"suffix)]

View File

@@ -22,29 +22,14 @@ error: suffixes on string literals are invalid
LL | #[must_use = "string"suffix] LL | #[must_use = "string"suffix]
| ^^^^^^^^^^^^^^ invalid suffix `suffix` | ^^^^^^^^^^^^^^ invalid suffix `suffix`
error: malformed `must_use` attribute input
--> $DIR/bad-lit-suffixes.rs:34:1
|
LL | #[must_use = "string"suffix]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: the following are the possible correct uses
|
LL - #[must_use = "string"suffix]
LL + #[must_use = "reason"]
|
LL - #[must_use = "string"suffix]
LL + #[must_use]
|
error: suffixes on string literals are invalid error: suffixes on string literals are invalid
--> $DIR/bad-lit-suffixes.rs:39:15 --> $DIR/bad-lit-suffixes.rs:38:15
| |
LL | #[link(name = "string"suffix)] LL | #[link(name = "string"suffix)]
| ^^^^^^^^^^^^^^ invalid suffix `suffix` | ^^^^^^^^^^^^^^ invalid suffix `suffix`
error: invalid suffix `suffix` for number literal error: invalid suffix `suffix` for number literal
--> $DIR/bad-lit-suffixes.rs:43:41 --> $DIR/bad-lit-suffixes.rs:42:41
| |
LL | #[rustc_layout_scalar_valid_range_start(0suffix)] LL | #[rustc_layout_scalar_valid_range_start(0suffix)]
| ^^^^^^^ invalid suffix `suffix` | ^^^^^^^ invalid suffix `suffix`
@@ -165,5 +150,5 @@ LL | 1.0e10suffix;
| |
= help: valid suffixes are `f32` and `f64` = help: valid suffixes are `f32` and `f64`
error: aborting due to 21 previous errors; 2 warnings emitted error: aborting due to 20 previous errors; 2 warnings emitted

View File

@@ -3,7 +3,7 @@ struct Foo {
//~^ ERROR struct fields are separated by `,` //~^ ERROR struct fields are separated by `,`
} }
union Bar { //~ ERROR union Bar {
foo: i32; foo: i32;
//~^ ERROR union fields are separated by `,` //~^ ERROR union fields are separated by `,`
} }
@@ -13,4 +13,6 @@ enum Baz {
//~^ ERROR struct fields are separated by `,` //~^ ERROR struct fields are separated by `,`
} }
fn main() {} fn main() {
let _ = Foo { foo: "" }; //~ ERROR mismatched types
}

View File

@@ -22,14 +22,12 @@ LL | Qux { foo: i32; }
| | | |
| while parsing this struct | while parsing this struct
error: unions cannot have zero fields error[E0308]: mismatched types
--> $DIR/recover-field-semi.rs:6:1 --> $DIR/recover-field-semi.rs:17:24
| |
LL | / union Bar { LL | let _ = Foo { foo: "" };
LL | | foo: i32; | ^^ expected `i32`, found `&str`
LL | |
LL | | }
| |_^
error: aborting due to 4 previous errors error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@@ -0,0 +1,17 @@
/// Check that only `&X: Debug` is required, not `X: Debug`
//@check-pass
use std::fmt::Debug;
use std::fmt::Formatter;
struct X;
impl Debug for &X {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
f.write_str("X")
}
}
fn main() {
dbg!(X);
}

View File

@@ -1,4 +1,7 @@
// Test ensuring that `dbg!(expr)` requires the passed type to implement `Debug`. // Test ensuring that `dbg!(expr)` requires the passed type to implement `Debug`.
//
// `dbg!` shouldn't tell the user about format literal syntax; the user didn't write one.
//@ forbid-output: cannot be formatted using
struct NotDebug; struct NotDebug;

View File

@@ -1,12 +1,11 @@
error[E0277]: `NotDebug` doesn't implement `Debug` error[E0277]: `NotDebug` doesn't implement `Debug`
--> $DIR/dbg-macro-requires-debug.rs:6:23 --> $DIR/dbg-macro-requires-debug.rs:9:23
| |
LL | let _: NotDebug = dbg!(NotDebug); LL | let _: NotDebug = dbg!(NotDebug);
| ^^^^^^^^^^^^^^ `NotDebug` cannot be formatted using `{:?}` | ^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `NotDebug`
| |
= help: the trait `Debug` is not implemented for `NotDebug`
= note: add `#[derive(Debug)]` to `NotDebug` or manually `impl Debug for NotDebug` = note: add `#[derive(Debug)]` to `NotDebug` or manually `impl Debug for NotDebug`
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `NotDebug` with `#[derive(Debug)]` help: consider annotating `NotDebug` with `#[derive(Debug)]`
| |
LL + #[derive(Debug)] LL + #[derive(Debug)]

View File

@@ -2,10 +2,8 @@ error[E0277]: `MyError` doesn't implement `std::fmt::Display`
--> $DIR/issue-71363.rs:4:28 --> $DIR/issue-71363.rs:4:28
| |
4 | impl std::error::Error for MyError {} 4 | impl std::error::Error for MyError {}
| ^^^^^^^ `MyError` cannot be formatted with the default formatter | ^^^^^^^ the trait `std::fmt::Display` is not implemented for `MyError`
| |
= help: the trait `std::fmt::Display` is not implemented for `MyError`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
note: required by a bound in `std::error::Error` note: required by a bound in `std::error::Error`
--> $SRC_DIR/core/src/error.rs:LL:COL --> $SRC_DIR/core/src/error.rs:LL:COL
@@ -13,9 +11,8 @@ error[E0277]: `MyError` doesn't implement `Debug`
--> $DIR/issue-71363.rs:4:28 --> $DIR/issue-71363.rs:4:28
| |
4 | impl std::error::Error for MyError {} 4 | impl std::error::Error for MyError {}
| ^^^^^^^ `MyError` cannot be formatted using `{:?}` | ^^^^^^^ the trait `Debug` is not implemented for `MyError`
| |
= help: the trait `Debug` is not implemented for `MyError`
= note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError` = note: add `#[derive(Debug)]` to `MyError` or manually `impl Debug for MyError`
note: required by a bound in `std::error::Error` note: required by a bound in `std::error::Error`
--> $SRC_DIR/core/src/error.rs:LL:COL --> $SRC_DIR/core/src/error.rs:LL:COL

View File

@@ -2,7 +2,9 @@ error[E0277]: `impl Sized` doesn't implement `Debug`
--> $DIR/bound-suggestions.rs:9:22 --> $DIR/bound-suggestions.rs:9:22
| |
LL | println!("{:?}", t); LL | println!("{:?}", t);
| ^ `impl Sized` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ---- ^ `impl Sized` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting opaque type `impl Sized` with trait `Debug` help: consider restricting opaque type `impl Sized` with trait `Debug`
@@ -14,7 +16,9 @@ error[E0277]: `T` doesn't implement `Debug`
--> $DIR/bound-suggestions.rs:15:22 --> $DIR/bound-suggestions.rs:15:22
| |
LL | println!("{:?}", t); LL | println!("{:?}", t);
| ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ---- ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T` with trait `Debug` help: consider restricting type parameter `T` with trait `Debug`
@@ -26,7 +30,9 @@ error[E0277]: `T` doesn't implement `Debug`
--> $DIR/bound-suggestions.rs:21:22 --> $DIR/bound-suggestions.rs:21:22
| |
LL | println!("{:?}", t); LL | println!("{:?}", t);
| ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ---- ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `T` with trait `Debug` help: consider further restricting type parameter `T` with trait `Debug`
@@ -38,7 +44,9 @@ error[E0277]: `Y` doesn't implement `Debug`
--> $DIR/bound-suggestions.rs:27:30 --> $DIR/bound-suggestions.rs:27:30
| |
LL | println!("{:?} {:?}", x, y); LL | println!("{:?} {:?}", x, y);
| ^ `Y` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ---- ^ `Y` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `Y` with trait `Debug` help: consider further restricting type parameter `Y` with trait `Debug`
@@ -50,7 +58,9 @@ error[E0277]: `X` doesn't implement `Debug`
--> $DIR/bound-suggestions.rs:33:22 --> $DIR/bound-suggestions.rs:33:22
| |
LL | println!("{:?}", x); LL | println!("{:?}", x);
| ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ---- ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `X` with trait `Debug` help: consider further restricting type parameter `X` with trait `Debug`
@@ -62,7 +72,9 @@ error[E0277]: `X` doesn't implement `Debug`
--> $DIR/bound-suggestions.rs:39:22 --> $DIR/bound-suggestions.rs:39:22
| |
LL | println!("{:?}", x); LL | println!("{:?}", x);
| ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ---- ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
| required by this formatting parameter
| |
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting type parameter `X` with trait `Debug` help: consider further restricting type parameter `X` with trait `Debug`

View File

@@ -4,9 +4,8 @@ error[E0277]: `a::Inner<T>` doesn't implement `Debug`
LL | #[derive(Debug)] LL | #[derive(Debug)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
LL | struct Outer<T>(Inner<T>); LL | struct Outer<T>(Inner<T>);
| ^^^^^^^^ `a::Inner<T>` cannot be formatted using `{:?}` | ^^^^^^^^ the trait `Debug` is not implemented for `a::Inner<T>`
| |
= help: the trait `Debug` is not implemented for `a::Inner<T>`
= note: add `#[derive(Debug)]` to `a::Inner<T>` or manually `impl Debug for a::Inner<T>` = note: add `#[derive(Debug)]` to `a::Inner<T>` or manually `impl Debug for a::Inner<T>`
help: consider annotating `a::Inner<T>` with `#[derive(Debug)]` help: consider annotating `a::Inner<T>` with `#[derive(Debug)]`
| |

View File

@@ -4,19 +4,16 @@ trait A: Sized {
fn f(a: A) -> A; fn f(a: A) -> A;
//~^ ERROR expected a type, found a trait //~^ ERROR expected a type, found a trait
//~| ERROR expected a type, found a trait //~| ERROR expected a type, found a trait
//~| ERROR associated item referring to unboxed trait object for its own trait
} }
trait B { trait B {
fn f(b: B) -> B; fn f(b: B) -> B;
//~^ ERROR expected a type, found a trait //~^ ERROR expected a type, found a trait
//~| ERROR expected a type, found a trait //~| ERROR expected a type, found a trait
//~| ERROR associated item referring to unboxed trait object for its own trait
} }
trait C { trait C {
fn f(&self, c: C) -> C; fn f(&self, c: C) -> C;
//~^ ERROR expected a type, found a trait //~^ ERROR expected a type, found a trait
//~| ERROR expected a type, found a trait //~| ERROR expected a type, found a trait
//~| ERROR associated item referring to unboxed trait object for its own trait
} }
fn main() {} fn main() {}

View File

@@ -26,22 +26,8 @@ help: `A` is dyn-incompatible, use `impl A` to return an opaque type, as long as
LL | fn f(a: A) -> impl A; LL | fn f(a: A) -> impl A;
| ++++ | ++++
error: associated item referring to unboxed trait object for its own trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:4:13
|
LL | trait A: Sized {
| - in this trait
LL | fn f(a: A) -> A;
| ^ ^
|
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn f(a: A) -> A;
LL + fn f(a: Self) -> Self;
|
error[E0782]: expected a type, found a trait error[E0782]: expected a type, found a trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:13 --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:9:13
| |
LL | fn f(b: B) -> B; LL | fn f(b: B) -> B;
| ^ | ^
@@ -58,7 +44,7 @@ LL | fn f(b: impl B) -> B;
| ++++ | ++++
error[E0782]: expected a type, found a trait error[E0782]: expected a type, found a trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:19 --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:9:19
| |
LL | fn f(b: B) -> B; LL | fn f(b: B) -> B;
| ^ | ^
@@ -68,22 +54,8 @@ help: `B` is dyn-incompatible, use `impl B` to return an opaque type, as long as
LL | fn f(b: B) -> impl B; LL | fn f(b: B) -> impl B;
| ++++ | ++++
error: associated item referring to unboxed trait object for its own trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:10:13
|
LL | trait B {
| - in this trait
LL | fn f(b: B) -> B;
| ^ ^
|
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn f(b: B) -> B;
LL + fn f(b: Self) -> Self;
|
error[E0782]: expected a type, found a trait error[E0782]: expected a type, found a trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:16:20 --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:14:20
| |
LL | fn f(&self, c: C) -> C; LL | fn f(&self, c: C) -> C;
| ^ | ^
@@ -100,7 +72,7 @@ LL | fn f(&self, c: impl C) -> C;
| ++++ | ++++
error[E0782]: expected a type, found a trait error[E0782]: expected a type, found a trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:16:26 --> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:14:26
| |
LL | fn f(&self, c: C) -> C; LL | fn f(&self, c: C) -> C;
| ^ | ^
@@ -110,20 +82,6 @@ help: `C` is dyn-incompatible, use `impl C` to return an opaque type, as long as
LL | fn f(&self, c: C) -> impl C; LL | fn f(&self, c: C) -> impl C;
| ++++ | ++++
error: associated item referring to unboxed trait object for its own trait error: aborting due to 6 previous errors
--> $DIR/dyn-incompatible-trait-should-use-self-2021-without-dyn.rs:16:20
|
LL | trait C {
| - in this trait
LL | fn f(&self, c: C) -> C;
| ^ ^
|
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn f(&self, c: C) -> C;
LL + fn f(&self, c: Self) -> Self;
|
error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0782`. For more information about this error, try `rustc --explain E0782`.

View File

@@ -2,13 +2,11 @@
#![allow(bare_trait_objects)] #![allow(bare_trait_objects)]
trait A: Sized { trait A: Sized {
fn f(a: dyn A) -> dyn A; fn f(a: dyn A) -> dyn A;
//~^ ERROR associated item referring to unboxed trait object for its own trait //~^ ERROR the trait `A` is not dyn compatible
//~| ERROR the trait `A` is not dyn compatible
} }
trait B { trait B {
fn f(a: dyn B) -> dyn B; fn f(a: dyn B) -> dyn B;
//~^ ERROR associated item referring to unboxed trait object for its own trait //~^ ERROR the trait `B` is not dyn compatible
//~| ERROR the trait `B` is not dyn compatible
} }
trait C { trait C {
fn f(&self, a: dyn C) -> dyn C; fn f(&self, a: dyn C) -> dyn C;

View File

@@ -1,17 +1,3 @@
error: associated item referring to unboxed trait object for its own trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:4:13
|
LL | trait A: Sized {
| - in this trait
LL | fn f(a: dyn A) -> dyn A;
| ^^^^^ ^^^^^
|
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn f(a: dyn A) -> dyn A;
LL + fn f(a: Self) -> Self;
|
error[E0038]: the trait `A` is not dyn compatible error[E0038]: the trait `A` is not dyn compatible
--> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:4:13 --> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:4:13
| |
@@ -26,30 +12,21 @@ LL | trait A: Sized {
| - ^^^^^ ...because it requires `Self: Sized` | - ^^^^^ ...because it requires `Self: Sized`
| | | |
| this trait is not dyn compatible... | this trait is not dyn compatible...
error: associated item referring to unboxed trait object for its own trait
--> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:9:13
|
LL | trait B {
| - in this trait
LL | fn f(a: dyn B) -> dyn B;
| ^^^^^ ^^^^^
|
help: you might have meant to use `Self` to refer to the implementing type help: you might have meant to use `Self` to refer to the implementing type
| |
LL - fn f(a: dyn B) -> dyn B; LL - fn f(a: dyn A) -> dyn A;
LL + fn f(a: Self) -> Self; LL + fn f(a: Self) -> dyn A;
| |
error[E0038]: the trait `B` is not dyn compatible error[E0038]: the trait `B` is not dyn compatible
--> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:9:13 --> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:8:13
| |
LL | fn f(a: dyn B) -> dyn B; LL | fn f(a: dyn B) -> dyn B;
| ^^^^^ `B` is not dyn compatible | ^^^^^ `B` is not dyn compatible
| |
note: for a trait to be dyn compatible it needs to allow building a vtable note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:9:8 --> $DIR/dyn-incompatible-trait-should-use-self-2021.rs:8:8
| |
LL | trait B { LL | trait B {
| - this trait is not dyn compatible... | - this trait is not dyn compatible...
@@ -63,7 +40,12 @@ help: alternatively, consider constraining `f` so it does not apply to trait obj
| |
LL | fn f(a: dyn B) -> dyn B where Self: Sized; LL | fn f(a: dyn B) -> dyn B where Self: Sized;
| +++++++++++++++++ | +++++++++++++++++
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn f(a: dyn B) -> dyn B;
LL + fn f(a: Self) -> dyn B;
|
error: aborting due to 4 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`. For more information about this error, try `rustc --explain E0038`.

View File

@@ -1,12 +1,10 @@
trait A: Sized { trait A: Sized {
fn f(a: dyn A) -> dyn A; fn f(a: dyn A) -> dyn A;
//~^ ERROR associated item referring to unboxed trait object for its own trait //~^ ERROR the trait `A` is not dyn compatible
//~| ERROR the trait `A` is not dyn compatible
} }
trait B { trait B {
fn f(a: dyn B) -> dyn B; fn f(a: dyn B) -> dyn B;
//~^ ERROR associated item referring to unboxed trait object for its own trait //~^ ERROR the trait `B` is not dyn compatible
//~| ERROR the trait `B` is not dyn compatible
} }
trait C { trait C {
fn f(&self, a: dyn C) -> dyn C; fn f(&self, a: dyn C) -> dyn C;

View File

@@ -1,17 +1,3 @@
error: associated item referring to unboxed trait object for its own trait
--> $DIR/dyn-incompatible-trait-should-use-self.rs:2:13
|
LL | trait A: Sized {
| - in this trait
LL | fn f(a: dyn A) -> dyn A;
| ^^^^^ ^^^^^
|
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn f(a: dyn A) -> dyn A;
LL + fn f(a: Self) -> Self;
|
error[E0038]: the trait `A` is not dyn compatible error[E0038]: the trait `A` is not dyn compatible
--> $DIR/dyn-incompatible-trait-should-use-self.rs:2:13 --> $DIR/dyn-incompatible-trait-should-use-self.rs:2:13
| |
@@ -26,30 +12,21 @@ LL | trait A: Sized {
| - ^^^^^ ...because it requires `Self: Sized` | - ^^^^^ ...because it requires `Self: Sized`
| | | |
| this trait is not dyn compatible... | this trait is not dyn compatible...
error: associated item referring to unboxed trait object for its own trait
--> $DIR/dyn-incompatible-trait-should-use-self.rs:7:13
|
LL | trait B {
| - in this trait
LL | fn f(a: dyn B) -> dyn B;
| ^^^^^ ^^^^^
|
help: you might have meant to use `Self` to refer to the implementing type help: you might have meant to use `Self` to refer to the implementing type
| |
LL - fn f(a: dyn B) -> dyn B; LL - fn f(a: dyn A) -> dyn A;
LL + fn f(a: Self) -> Self; LL + fn f(a: Self) -> dyn A;
| |
error[E0038]: the trait `B` is not dyn compatible error[E0038]: the trait `B` is not dyn compatible
--> $DIR/dyn-incompatible-trait-should-use-self.rs:7:13 --> $DIR/dyn-incompatible-trait-should-use-self.rs:6:13
| |
LL | fn f(a: dyn B) -> dyn B; LL | fn f(a: dyn B) -> dyn B;
| ^^^^^ `B` is not dyn compatible | ^^^^^ `B` is not dyn compatible
| |
note: for a trait to be dyn compatible it needs to allow building a vtable note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/dyn-incompatible-trait-should-use-self.rs:7:8 --> $DIR/dyn-incompatible-trait-should-use-self.rs:6:8
| |
LL | trait B { LL | trait B {
| - this trait is not dyn compatible... | - this trait is not dyn compatible...
@@ -63,7 +40,12 @@ help: alternatively, consider constraining `f` so it does not apply to trait obj
| |
LL | fn f(a: dyn B) -> dyn B where Self: Sized; LL | fn f(a: dyn B) -> dyn B where Self: Sized;
| +++++++++++++++++ | +++++++++++++++++
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn f(a: dyn B) -> dyn B;
LL + fn f(a: Self) -> dyn B;
|
error: aborting due to 4 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`. For more information about this error, try `rustc --explain E0038`.

View File

@@ -2,11 +2,10 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
--> $DIR/impl-trait-with-missing-bounds.rs:6:13 --> $DIR/impl-trait-with-missing-bounds.rs:6:13
| |
LL | qux(constraint); LL | qux(constraint);
| --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` | --- ^^^^^^^^^^ the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
note: required by a bound in `qux` note: required by a bound in `qux`
--> $DIR/impl-trait-with-missing-bounds.rs:50:16 --> $DIR/impl-trait-with-missing-bounds.rs:50:16
| |
@@ -22,11 +21,10 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
--> $DIR/impl-trait-with-missing-bounds.rs:14:13 --> $DIR/impl-trait-with-missing-bounds.rs:14:13
| |
LL | qux(constraint); LL | qux(constraint);
| --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` | --- ^^^^^^^^^^ the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
note: required by a bound in `qux` note: required by a bound in `qux`
--> $DIR/impl-trait-with-missing-bounds.rs:50:16 --> $DIR/impl-trait-with-missing-bounds.rs:50:16
| |
@@ -42,11 +40,10 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
--> $DIR/impl-trait-with-missing-bounds.rs:22:13 --> $DIR/impl-trait-with-missing-bounds.rs:22:13
| |
LL | qux(constraint); LL | qux(constraint);
| --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` | --- ^^^^^^^^^^ the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
note: required by a bound in `qux` note: required by a bound in `qux`
--> $DIR/impl-trait-with-missing-bounds.rs:50:16 --> $DIR/impl-trait-with-missing-bounds.rs:50:16
| |
@@ -62,11 +59,10 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
--> $DIR/impl-trait-with-missing-bounds.rs:30:13 --> $DIR/impl-trait-with-missing-bounds.rs:30:13
| |
LL | qux(constraint); LL | qux(constraint);
| --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` | --- ^^^^^^^^^^ the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
note: required by a bound in `qux` note: required by a bound in `qux`
--> $DIR/impl-trait-with-missing-bounds.rs:50:16 --> $DIR/impl-trait-with-missing-bounds.rs:50:16
| |
@@ -82,11 +78,10 @@ error[E0277]: `<impl Iterator + std::fmt::Debug as Iterator>::Item` doesn't impl
--> $DIR/impl-trait-with-missing-bounds.rs:37:13 --> $DIR/impl-trait-with-missing-bounds.rs:37:13
| |
LL | qux(constraint); LL | qux(constraint);
| --- ^^^^^^^^^^ `<impl Iterator + std::fmt::Debug as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` | --- ^^^^^^^^^^ the trait `Debug` is not implemented for `<impl Iterator + std::fmt::Debug as Iterator>::Item`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `Debug` is not implemented for `<impl Iterator + std::fmt::Debug as Iterator>::Item`
note: required by a bound in `qux` note: required by a bound in `qux`
--> $DIR/impl-trait-with-missing-bounds.rs:50:16 --> $DIR/impl-trait-with-missing-bounds.rs:50:16
| |
@@ -102,11 +97,10 @@ error[E0277]: `<impl Iterator as Iterator>::Item` doesn't implement `Debug`
--> $DIR/impl-trait-with-missing-bounds.rs:45:13 --> $DIR/impl-trait-with-missing-bounds.rs:45:13
| |
LL | qux(constraint); LL | qux(constraint);
| --- ^^^^^^^^^^ `<impl Iterator as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug` | --- ^^^^^^^^^^ the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
| | | |
| required by a bound introduced by this call | required by a bound introduced by this call
| |
= help: the trait `Debug` is not implemented for `<impl Iterator as Iterator>::Item`
note: required by a bound in `qux` note: required by a bound in `qux`
--> $DIR/impl-trait-with-missing-bounds.rs:50:16 --> $DIR/impl-trait-with-missing-bounds.rs:50:16
| |

View File

@@ -11,6 +11,7 @@ trait Foo {
//~| HELP if this is a dyn-compatible trait, use `dyn` //~| HELP if this is a dyn-compatible trait, use `dyn`
//~| ERROR the trait `Clone` is not dyn compatible [E0038] //~| ERROR the trait `Clone` is not dyn compatible [E0038]
//~| HELP there is an associated type with the same name //~| HELP there is an associated type with the same name
//~| HELP use `Self` to refer to the implementing type
} }
trait DbHandle: Sized {} trait DbHandle: Sized {}
@@ -26,6 +27,7 @@ trait DbInterface {
//~| HELP if this is a dyn-compatible trait, use `dyn` //~| HELP if this is a dyn-compatible trait, use `dyn`
//~| ERROR the trait `DbHandle` is not dyn compatible [E0038] //~| ERROR the trait `DbHandle` is not dyn compatible [E0038]
//~| HELP there is an associated type with the same name //~| HELP there is an associated type with the same name
//~| HELP use `Self` to refer to the implementing type
} }
fn main() {} fn main() {}

View File

@@ -35,13 +35,18 @@ LL | fn foo() -> Clone;
= note: the trait is not dyn compatible because it requires `Self: Sized` = note: the trait is not dyn compatible because it requires `Self: Sized`
= note: for a trait to be dyn compatible it needs to allow building a vtable = note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn foo() -> Clone;
LL + fn foo() -> Self;
|
help: there is an associated type with the same name help: there is an associated type with the same name
| |
LL | fn foo() -> Self::Clone; LL | fn foo() -> Self::Clone;
| ++++++ | ++++++
warning: trait objects without an explicit `dyn` are deprecated warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-116434-2015.rs:20:20 --> $DIR/issue-116434-2015.rs:21:20
| |
LL | fn handle() -> DbHandle; LL | fn handle() -> DbHandle;
| ^^^^^^^^ | ^^^^^^^^
@@ -54,7 +59,7 @@ LL | fn handle() -> dyn DbHandle;
| +++ | +++
warning: trait objects without an explicit `dyn` are deprecated warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-116434-2015.rs:20:20 --> $DIR/issue-116434-2015.rs:21:20
| |
LL | fn handle() -> DbHandle; LL | fn handle() -> DbHandle;
| ^^^^^^^^ | ^^^^^^^^
@@ -68,19 +73,24 @@ LL | fn handle() -> dyn DbHandle;
| +++ | +++
error[E0038]: the trait `DbHandle` is not dyn compatible error[E0038]: the trait `DbHandle` is not dyn compatible
--> $DIR/issue-116434-2015.rs:20:20 --> $DIR/issue-116434-2015.rs:21:20
| |
LL | fn handle() -> DbHandle; LL | fn handle() -> DbHandle;
| ^^^^^^^^ `DbHandle` is not dyn compatible | ^^^^^^^^ `DbHandle` is not dyn compatible
| |
note: for a trait to be dyn compatible it needs to allow building a vtable note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility> for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/issue-116434-2015.rs:16:17 --> $DIR/issue-116434-2015.rs:17:17
| |
LL | trait DbHandle: Sized {} LL | trait DbHandle: Sized {}
| -------- ^^^^^ ...because it requires `Self: Sized` | -------- ^^^^^ ...because it requires `Self: Sized`
| | | |
| this trait is not dyn compatible... | this trait is not dyn compatible...
help: you might have meant to use `Self` to refer to the implementing type
|
LL - fn handle() -> DbHandle;
LL + fn handle() -> Self;
|
help: there is an associated type with the same name help: there is an associated type with the same name
| |
LL | fn handle() -> Self::DbHandle; LL | fn handle() -> Self::DbHandle;

View File

@@ -2,23 +2,17 @@ error[E0277]: `()` doesn't implement `std::fmt::Display`
--> $DIR/issue-81098.rs:3:13 --> $DIR/issue-81098.rs:3:13
| |
LL | fn wat() -> impl core::fmt::Display { LL | fn wat() -> impl core::fmt::Display {
| ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::fmt::Display` is not implemented for `()`
|
= help: the trait `std::fmt::Display` is not implemented for `()`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
error[E0277]: `()` doesn't implement `std::fmt::Display` error[E0277]: `()` doesn't implement `std::fmt::Display`
--> $DIR/issue-81098.rs:9:12 --> $DIR/issue-81098.rs:9:12
| |
LL | fn ok() -> impl core::fmt::Display { LL | fn ok() -> impl core::fmt::Display {
| ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::fmt::Display` is not implemented for `()`
LL | 1; LL | 1;
| -- help: remove this semicolon | -- help: remove this semicolon
| | | |
| this expression has type `{integer}`, which implements `std::fmt::Display` | this expression has type `{integer}`, which implements `std::fmt::Display`
|
= help: the trait `std::fmt::Display` is not implemented for `()`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@@ -2,7 +2,10 @@ error[E0277]: `<impl IntoIterator as IntoIterator>::Item` doesn't implement `std
--> $DIR/issue-97760.rs:4:20 --> $DIR/issue-97760.rs:4:20
| |
LL | println!("{x}"); LL | println!("{x}");
| ^ `<impl IntoIterator as IntoIterator>::Item` cannot be formatted with the default formatter | -^-
| ||
| |`<impl IntoIterator as IntoIterator>::Item` cannot be formatted with the default formatter
| required by this formatting parameter
| |
= help: the trait `std::fmt::Display` is not implemented for `<impl IntoIterator as IntoIterator>::Item` = help: the trait `std::fmt::Display` is not implemented for `<impl IntoIterator as IntoIterator>::Item`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead

View File

@@ -21,7 +21,7 @@ error[E0277]: `K` doesn't implement `Debug`
--> $DIR/missing-bound-in-derive-copy-impl-3.rs:12:14 --> $DIR/missing-bound-in-derive-copy-impl-3.rs:12:14
| |
LL | pub loc: Vector2<K>, LL | pub loc: Vector2<K>,
| ^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^ the trait `Debug` is not implemented for `K`
| |
note: required by a bound in `Vector2` note: required by a bound in `Vector2`
--> $DIR/missing-bound-in-derive-copy-impl-3.rs:5:23 --> $DIR/missing-bound-in-derive-copy-impl-3.rs:5:23
@@ -40,7 +40,7 @@ LL | #[derive(Debug, Copy, Clone)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
LL | pub struct AABB<K: Copy>{ LL | pub struct AABB<K: Copy>{
LL | pub loc: Vector2<K>, LL | pub loc: Vector2<K>,
| ^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `K`
| |
help: consider further restricting type parameter `K` with trait `Debug` help: consider further restricting type parameter `K` with trait `Debug`
| |
@@ -54,7 +54,7 @@ LL | #[derive(Debug, Copy, Clone)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
... ...
LL | pub size: Vector2<K> LL | pub size: Vector2<K>
| ^^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `K`
| |
help: consider further restricting type parameter `K` with trait `Debug` help: consider further restricting type parameter `K` with trait `Debug`
| |

View File

@@ -21,7 +21,7 @@ error[E0277]: `K` doesn't implement `Debug`
--> $DIR/missing-bound-in-derive-copy-impl.rs:11:14 --> $DIR/missing-bound-in-derive-copy-impl.rs:11:14
| |
LL | pub loc: Vector2<K>, LL | pub loc: Vector2<K>,
| ^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^ the trait `Debug` is not implemented for `K`
| |
note: required by a bound in `Vector2` note: required by a bound in `Vector2`
--> $DIR/missing-bound-in-derive-copy-impl.rs:4:23 --> $DIR/missing-bound-in-derive-copy-impl.rs:4:23
@@ -78,7 +78,7 @@ LL | #[derive(Debug, Copy, Clone)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
LL | pub struct AABB<K> { LL | pub struct AABB<K> {
LL | pub loc: Vector2<K>, LL | pub loc: Vector2<K>,
| ^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `K`
| |
help: consider restricting type parameter `K` with trait `Debug` help: consider restricting type parameter `K` with trait `Debug`
| |
@@ -111,7 +111,7 @@ LL | #[derive(Debug, Copy, Clone)]
| ----- in this derive macro expansion | ----- in this derive macro expansion
... ...
LL | pub size: Vector2<K>, LL | pub size: Vector2<K>,
| ^^^^^^^^^^^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `K`
| |
help: consider restricting type parameter `K` with trait `Debug` help: consider restricting type parameter `K` with trait `Debug`
| |

Some files were not shown because too many files have changed in this diff Show More