Skip to content

Commit 111e9bc

Browse files
committed
Auto merge of #142878 - GuillaumeGomez:rollup-53dohob, r=GuillaumeGomez
Rollup of 10 pull requests Successful merges: - #142458 (Merge unboxed trait object error suggestion into regular dyn incompat error) - #142593 (Add a warning to LateContext::get_def_path) - #142594 (Add DesugaringKind::FormatLiteral) - #142740 (Clean-up `FnCtxt::is_destruct_assignment_desugaring`) - #142780 (Port `#[must_use]` to new attribute parsing infrastructure) - #142798 (Don't fail to parse a struct if a semicolon is used to separate fields) - #142856 (Add a few inline directives in rustc_serialize.) - #142868 (remove few allow(dead_code)) - #142874 (cranelift: fix target feature name typo: "fxsr") - #142877 (Document why tidy checks if `eslint` is installed via `npm`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c2ec753 + 8da1a62 commit 111e9bc

File tree

114 files changed

+594
-515
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+594
-515
lines changed

compiler/rustc_ast/src/format.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ pub struct FormatArgs {
5050
///
5151
/// Generally only useful for lints that care about the raw bytes the user wrote.
5252
pub uncooked_fmt_str: (LitKind, Symbol),
53+
/// Was the format literal written in the source?
54+
/// - `format!("boo")` => true,
55+
/// - `format!(concat!("b", "o", "o"))` => false,
56+
/// - `format!(include_str!("boo.txt"))` => false,
57+
///
58+
/// If it wasn't written in the source then we have to be careful with spans pointing into it
59+
/// and suggestions about rewriting it.
60+
pub is_source_literal: bool,
5361
}
5462

5563
/// A piece of a format template string.

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1566,7 +1566,7 @@ macro_rules! common_visitor_and_walkers {
15661566

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

compiler/rustc_ast_lowering/src/format.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_ast::*;
44
use rustc_data_structures::fx::FxIndexMap;
55
use rustc_hir as hir;
66
use rustc_session::config::FmtDebug;
7-
use rustc_span::{Ident, Span, Symbol, sym};
7+
use rustc_span::{DesugaringKind, Ident, Span, Symbol, sym};
88

99
use super::LoweringContext;
1010

@@ -14,6 +14,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
1414
// format_args!() had any arguments _before_ flattening/inlining.
1515
let allow_const = fmt.arguments.all_args().is_empty();
1616
let mut fmt = Cow::Borrowed(fmt);
17+
18+
let sp = self.mark_span_with_reason(
19+
DesugaringKind::FormatLiteral { source: fmt.is_source_literal },
20+
sp,
21+
sp.ctxt().outer_expn_data().allow_internal_unstable,
22+
);
23+
1724
if self.tcx.sess.opts.unstable_opts.flatten_format_args {
1825
fmt = flatten_format_args(fmt);
1926
fmt = self.inline_literals(fmt);

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,13 @@ pub enum AttributeKind {
237237
/// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html).
238238
MayDangle(Span),
239239

240+
/// Represents `#[must_use]`.
241+
MustUse {
242+
span: Span,
243+
/// must_use can optionally have a reason: `#[must_use = "reason this must be used"]`
244+
reason: Option<Symbol>,
245+
},
246+
240247
/// Represents `#[optimize(size|speed)]`
241248
Optimize(OptimizeAttr, Span),
242249

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub(crate) mod confusables;
3333
pub(crate) mod deprecation;
3434
pub(crate) mod inline;
3535
pub(crate) mod lint_helpers;
36+
pub(crate) mod must_use;
3637
pub(crate) mod repr;
3738
pub(crate) mod semantics;
3839
pub(crate) mod stability;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use rustc_attr_data_structures::AttributeKind;
2+
use rustc_errors::DiagArgValue;
3+
use rustc_feature::{AttributeTemplate, template};
4+
use rustc_span::{Symbol, sym};
5+
6+
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
7+
use crate::context::{AcceptContext, Stage};
8+
use crate::parser::ArgParser;
9+
use crate::session_diagnostics;
10+
11+
pub(crate) struct MustUseParser;
12+
13+
impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
14+
const PATH: &[Symbol] = &[sym::must_use];
15+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
16+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
17+
const TEMPLATE: AttributeTemplate = template!(Word, NameValueStr: "reason");
18+
19+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
20+
Some(AttributeKind::MustUse {
21+
span: cx.attr_span,
22+
reason: match args {
23+
ArgParser::NoArgs => None,
24+
ArgParser::NameValue(name_value) => name_value.value_as_str(),
25+
ArgParser::List(_) => {
26+
let suggestions =
27+
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "must_use");
28+
cx.emit_err(session_diagnostics::MustUseIllFormedAttributeInput {
29+
num_suggestions: suggestions.len(),
30+
suggestions: DiagArgValue::StrListSepByAnd(
31+
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
32+
),
33+
span: cx.attr_span,
34+
});
35+
return None;
36+
}
37+
},
38+
})
39+
}
40+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::attributes::confusables::ConfusablesParser;
2020
use crate::attributes::deprecation::DeprecationParser;
2121
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
2222
use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser};
23+
use crate::attributes::must_use::MustUseParser;
2324
use crate::attributes::repr::{AlignParser, ReprParser};
2425
use crate::attributes::semantics::MayDangleParser;
2526
use crate::attributes::stability::{
@@ -112,6 +113,7 @@ attribute_parsers!(
112113
Single<DeprecationParser>,
113114
Single<InlineParser>,
114115
Single<MayDangleParser>,
116+
Single<MustUseParser>,
115117
Single<OptimizeParser>,
116118
Single<PubTransparentParser>,
117119
Single<RustcForceInlineParser>,

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,15 @@ pub(crate) struct IllFormedAttributeInput {
436436
pub suggestions: DiagArgValue,
437437
}
438438

439+
#[derive(Diagnostic)]
440+
#[diag(attr_parsing_ill_formed_attribute_input)]
441+
pub(crate) struct MustUseIllFormedAttributeInput {
442+
#[primary_span]
443+
pub span: Span,
444+
pub num_suggestions: usize,
445+
pub suggestions: DiagArgValue,
446+
}
447+
439448
#[derive(Diagnostic)]
440449
#[diag(attr_parsing_stability_outside_std, code = E0734)]
441450
pub(crate) struct StabilityOutsideStd {

compiler/rustc_builtin_macros/src/format.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,7 @@ fn make_format_args(
606606
template,
607607
arguments: args,
608608
uncooked_fmt_str,
609+
is_source_literal,
609610
}))
610611
}
611612

compiler/rustc_codegen_cranelift/src/lib.rs

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

compiler/rustc_data_structures/src/sync/lock.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
//! This module implements a lock which only uses synchronization if `might_be_dyn_thread_safe` is true.
22
//! It implements `DynSend` and `DynSync` instead of the typical `Send` and `Sync` traits.
33
4-
#![allow(dead_code)]
5-
64
use std::fmt;
75

86
#[derive(Clone, Copy, PartialEq)]

compiler/rustc_data_structures/src/sync/parallel.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
//! This module defines parallel operations that are implemented in
22
//! one way for the serial compiler, and another way the parallel compiler.
33
4-
#![allow(dead_code)]
5-
64
use std::any::Any;
75
use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
86

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -382,8 +382,6 @@ fn check_trait_item<'tcx>(
382382
_ => (None, trait_item.span),
383383
};
384384

385-
check_dyn_incompatible_self_trait_by_name(tcx, trait_item);
386-
387385
// Check that an item definition in a subtrait is shadowing a supertrait item.
388386
lint_item_shadowing_supertrait_item(tcx, def_id);
389387

@@ -832,70 +830,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
832830
}
833831
}
834832

835-
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
836-
match ty.kind {
837-
hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
838-
[s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
839-
_ => false,
840-
},
841-
_ => false,
842-
}
843-
}
844-
845-
/// Detect when a dyn-incompatible trait is referring to itself in one of its associated items.
846-
///
847-
/// In such cases, suggest using `Self` instead.
848-
fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem<'_>) {
849-
let (trait_ident, trait_def_id) =
850-
match tcx.hir_node_by_def_id(tcx.hir_get_parent_item(item.hir_id()).def_id) {
851-
hir::Node::Item(item) => match item.kind {
852-
hir::ItemKind::Trait(_, _, ident, ..) => (ident, item.owner_id),
853-
_ => return,
854-
},
855-
_ => return,
856-
};
857-
let mut trait_should_be_self = vec![];
858-
match &item.kind {
859-
hir::TraitItemKind::Const(ty, _) | hir::TraitItemKind::Type(_, Some(ty))
860-
if could_be_self(trait_def_id.def_id, ty) =>
861-
{
862-
trait_should_be_self.push(ty.span)
863-
}
864-
hir::TraitItemKind::Fn(sig, _) => {
865-
for ty in sig.decl.inputs {
866-
if could_be_self(trait_def_id.def_id, ty) {
867-
trait_should_be_self.push(ty.span);
868-
}
869-
}
870-
match sig.decl.output {
871-
hir::FnRetTy::Return(ty) if could_be_self(trait_def_id.def_id, ty) => {
872-
trait_should_be_self.push(ty.span);
873-
}
874-
_ => {}
875-
}
876-
}
877-
_ => {}
878-
}
879-
if !trait_should_be_self.is_empty() {
880-
if tcx.is_dyn_compatible(trait_def_id) {
881-
return;
882-
}
883-
let sugg = trait_should_be_self.iter().map(|span| (*span, "Self".to_string())).collect();
884-
tcx.dcx()
885-
.struct_span_err(
886-
trait_should_be_self,
887-
"associated item referring to unboxed trait object for its own trait",
888-
)
889-
.with_span_label(trait_ident.span, "in this trait")
890-
.with_multipart_suggestion(
891-
"you might have meant to use `Self` to refer to the implementing type",
892-
sugg,
893-
Applicability::MachineApplicable,
894-
)
895-
.emit();
896-
}
897-
}
898-
899833
fn lint_item_shadowing_supertrait_item<'tcx>(tcx: TyCtxt<'tcx>, trait_item_def_id: LocalDefId) {
900834
let item_name = tcx.item_name(trait_item_def_id.to_def_id());
901835
let trait_def_id = tcx.local_parent(trait_item_def_id);

compiler/rustc_hir_analysis/src/hir_wf_check.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use rustc_hir::def::DefKind;
12
use rustc_hir::intravisit::{self, Visitor, VisitorExt};
23
use rustc_hir::{self as hir, AmbigArg, ForeignItem, ForeignItemKind};
34
use rustc_infer::infer::TyCtxtInferExt;
4-
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
5+
use rustc_infer::traits::{ObligationCause, ObligationCauseCode, WellFormedLoc};
56
use rustc_middle::bug;
67
use rustc_middle::query::Providers;
78
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode, fold_regions};
@@ -107,6 +108,17 @@ fn diagnostic_hir_wf_check<'tcx>(
107108
// over less-specific types (e.g. `Option<MyStruct<u8>>`)
108109
if self.depth >= self.cause_depth {
109110
self.cause = Some(error.obligation.cause);
111+
if let hir::TyKind::TraitObject(..) = ty.kind {
112+
if let DefKind::AssocTy | DefKind::AssocConst | DefKind::AssocFn =
113+
self.tcx.def_kind(self.def_id)
114+
{
115+
self.cause = Some(ObligationCause::new(
116+
ty.span,
117+
self.def_id,
118+
ObligationCauseCode::DynCompatible(ty.span),
119+
));
120+
}
121+
}
110122
self.cause_depth = self.depth
111123
}
112124
}

compiler/rustc_hir_typeck/src/demand.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,27 +1110,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11101110
}
11111111
}
11121112

1113-
// Returns whether the given expression is a destruct assignment desugaring.
1114-
// For example, `(a, b) = (1, &2);`
1115-
// Here we try to find the pattern binding of the expression,
1116-
// `default_binding_modes` is false only for destruct assignment desugaring.
1113+
/// Returns whether the given expression is a destruct assignment desugaring.
1114+
/// For example, `(a, b) = (1, &2);`
1115+
/// Here we try to find the pattern binding of the expression,
1116+
/// `default_binding_modes` is false only for destruct assignment desugaring.
11171117
pub(crate) fn is_destruct_assignment_desugaring(&self, expr: &hir::Expr<'_>) -> bool {
11181118
if let hir::ExprKind::Path(hir::QPath::Resolved(
11191119
_,
11201120
hir::Path { res: hir::def::Res::Local(bind_hir_id), .. },
11211121
)) = expr.kind
1122-
{
1123-
let bind = self.tcx.hir_node(*bind_hir_id);
1124-
let parent = self.tcx.parent_hir_node(*bind_hir_id);
1125-
if let hir::Node::Pat(hir::Pat {
1122+
&& let bind = self.tcx.hir_node(*bind_hir_id)
1123+
&& let parent = self.tcx.parent_hir_node(*bind_hir_id)
1124+
&& let hir::Node::Pat(hir::Pat {
11261125
kind: hir::PatKind::Binding(_, _hir_id, _, _), ..
11271126
}) = bind
1128-
&& let hir::Node::Pat(hir::Pat { default_binding_modes: false, .. }) = parent
1129-
{
1130-
return true;
1131-
}
1127+
&& let hir::Node::Pat(hir::Pat { default_binding_modes: false, .. }) = parent
1128+
{
1129+
true
1130+
} else {
1131+
false
11321132
}
1133-
false
11341133
}
11351134

11361135
fn explain_self_literal(

compiler/rustc_lint/src/context.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,15 @@ impl<'tcx> LateContext<'tcx> {
711711

712712
/// Gets the absolute path of `def_id` as a vector of `Symbol`.
713713
///
714+
/// Note that this is kinda expensive because it has to
715+
/// travel the tree and pretty-print. Use sparingly.
716+
///
717+
/// If you're trying to match for an item given by its path, use a
718+
/// diagnostic item. If you're only interested in given sections, use more
719+
/// specific functions, such as [`TyCtxt::crate_name`]
720+
///
721+
/// FIXME: It would be great if this could be optimized.
722+
///
714723
/// # Examples
715724
///
716725
/// ```rust,ignore (no context or def id available)

compiler/rustc_lint/src/unused.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::iter;
22

33
use rustc_ast::util::{classify, parser};
44
use rustc_ast::{self as ast, ExprKind, HasAttrs as _, StmtKind};
5+
use rustc_attr_data_structures::{AttributeKind, find_attr};
56
use rustc_errors::{MultiSpan, pluralize};
67
use rustc_hir::def::{DefKind, Res};
78
use rustc_hir::def_id::DefId;
@@ -368,10 +369,12 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
368369
}
369370

370371
fn is_def_must_use(cx: &LateContext<'_>, def_id: DefId, span: Span) -> Option<MustUsePath> {
371-
if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) {
372+
if let Some(reason) = find_attr!(
373+
cx.tcx.get_all_attrs(def_id),
374+
AttributeKind::MustUse { reason, .. } => reason
375+
) {
372376
// check for #[must_use = "..."]
373-
let reason = attr.value_str();
374-
Some(MustUsePath::Def(span, def_id, reason))
377+
Some(MustUsePath::Def(span, def_id, *reason))
375378
} else {
376379
None
377380
}

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,8 @@ pub enum ObligationCauseCode<'tcx> {
397397

398398
RustCall,
399399

400+
DynCompatible(Span),
401+
400402
/// Obligations to prove that a `Drop` or negative auto trait impl is not stronger than
401403
/// the ADT it's being implemented for.
402404
AlwaysApplicableImpl,

0 commit comments

Comments
 (0)