Skip to content

Commit fe1bf8e

Browse files
committed
Auto merge of rust-lang#82443 - Dylan-DPC:rollup-yni7uio, r=Dylan-DPC
Rollup of 10 pull requests Successful merges: - rust-lang#81629 (Point out implicit deref coercions in borrow) - rust-lang#82113 (Improve non_fmt_panic lint.) - rust-lang#82258 (Implement -Z hir-stats for nested foreign items) - rust-lang#82296 (Support `pub` on `macro_rules`) - rust-lang#82297 (Consider auto derefs before warning about write only fields) - rust-lang#82305 (Remove many RefCells from DocContext) - rust-lang#82308 (Lower condition of `if` expression before it's "then" block) - rust-lang#82311 (Jsondocck improvements) - rust-lang#82362 (Fix mir-cfg dumps) - rust-lang#82391 (disable atomic_max/min tests in Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0196107 + 51511c7 commit fe1bf8e

File tree

66 files changed

+1160
-157
lines changed

Some content is hidden

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

66 files changed

+1160
-157
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
347347
) -> hir::ExprKind<'hir> {
348348
macro_rules! make_if {
349349
($opt:expr) => {{
350+
let cond = self.lower_expr(cond);
350351
let then_expr = self.lower_block_expr(then);
351-
hir::ExprKind::If(self.lower_expr(cond), self.arena.alloc(then_expr), $opt)
352+
hir::ExprKind::If(cond, self.arena.alloc(then_expr), $opt)
352353
}};
353354
}
354355
if let Some(rslt) = else_opt {

compiler/rustc_ast_passes/src/feature_gate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
665665
// involved, so we only emit errors where there are no other parsing errors.
666666
gate_all!(destructuring_assignment, "destructuring assignments are unstable");
667667
}
668+
gate_all!(pub_macro_rules, "`pub` on `macro_rules` items is unstable");
668669

669670
// All uses of `gate_all!` below this point were added in #65742,
670671
// and subsequently disabled (with the non-early gating readded).

compiler/rustc_feature/src/active.rs

+3
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@ declare_features! (
638638
/// Allows macro attributes to observe output of `#[derive]`.
639639
(active, macro_attributes_in_derive_output, "1.51.0", Some(81119), None),
640640

641+
/// Allows `pub` on `macro_rules` items.
642+
(active, pub_macro_rules, "1.52.0", Some(78855), None),
643+
641644
// -------------------------------------------------------------------------
642645
// feature-group-end: actual feature gates
643646
// -------------------------------------------------------------------------

compiler/rustc_lint/src/non_fmt_panic.rs

+64-9
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,65 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
6969

7070
let (span, panic) = panic_call(cx, f);
7171

72-
cx.struct_span_lint(NON_FMT_PANIC, arg.span, |lint| {
72+
// Find the span of the argument to `panic!()`, before expansion in the
73+
// case of `panic!(some_macro!())`.
74+
// We don't use source_callsite(), because this `panic!(..)` might itself
75+
// be expanded from another macro, in which case we want to stop at that
76+
// expansion.
77+
let mut arg_span = arg.span;
78+
let mut arg_macro = None;
79+
while !span.contains(arg_span) {
80+
let expn = arg_span.ctxt().outer_expn_data();
81+
if expn.is_root() {
82+
break;
83+
}
84+
arg_macro = expn.macro_def_id;
85+
arg_span = expn.call_site;
86+
}
87+
88+
cx.struct_span_lint(NON_FMT_PANIC, arg_span, |lint| {
7389
let mut l = lint.build("panic message is not a string literal");
7490
l.note("this is no longer accepted in Rust 2021");
75-
if span.contains(arg.span) {
91+
if !span.contains(arg_span) {
92+
// No clue where this argument is coming from.
93+
l.emit();
94+
return;
95+
}
96+
if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
97+
// A case of `panic!(format!(..))`.
98+
l.note("the panic!() macro supports formatting, so there's no need for the format!() macro here");
99+
if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
100+
l.multipart_suggestion(
101+
"remove the `format!(..)` macro call",
102+
vec![
103+
(arg_span.until(open.shrink_to_hi()), "".into()),
104+
(close.until(arg_span.shrink_to_hi()), "".into()),
105+
],
106+
Applicability::MachineApplicable,
107+
);
108+
}
109+
} else {
76110
l.span_suggestion_verbose(
77-
arg.span.shrink_to_lo(),
111+
arg_span.shrink_to_lo(),
78112
"add a \"{}\" format string to Display the message",
79113
"\"{}\", ".into(),
80114
Applicability::MaybeIncorrect,
81115
);
82116
if panic == sym::std_panic_macro {
83-
l.span_suggestion_verbose(
84-
span.until(arg.span),
85-
"or use std::panic::panic_any instead",
86-
"std::panic::panic_any(".into(),
87-
Applicability::MachineApplicable,
88-
);
117+
if let Some((open, close, del)) = find_delimiters(cx, span) {
118+
l.multipart_suggestion(
119+
"or use std::panic::panic_any instead",
120+
if del == '(' {
121+
vec![(span.until(open), "std::panic::panic_any".into())]
122+
} else {
123+
vec![
124+
(span.until(open.shrink_to_hi()), "std::panic::panic_any(".into()),
125+
(close, ")".into()),
126+
]
127+
},
128+
Applicability::MachineApplicable,
129+
);
130+
}
89131
}
90132
}
91133
l.emit();
@@ -175,6 +217,19 @@ fn check_panic_str<'tcx>(
175217
}
176218
}
177219

220+
/// Given the span of `some_macro!(args);`, gives the span of `(` and `)`,
221+
/// and the type of (opening) delimiter used.
222+
fn find_delimiters<'tcx>(cx: &LateContext<'tcx>, span: Span) -> Option<(Span, Span, char)> {
223+
let snippet = cx.sess().parse_sess.source_map().span_to_snippet(span).ok()?;
224+
let (open, open_ch) = snippet.char_indices().find(|&(_, c)| "([{".contains(c))?;
225+
let close = snippet.rfind(|c| ")]}".contains(c))?;
226+
Some((
227+
span.from_inner(InnerSpan { start: open, end: open + 1 }),
228+
span.from_inner(InnerSpan { start: close, end: close + 1 }),
229+
open_ch,
230+
))
231+
}
232+
178233
fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span, Symbol) {
179234
let mut expn = f.span.ctxt().outer_expn_data();
180235

compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs

+37-4
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ use rustc_index::vec::Idx;
88
use rustc_middle::mir::{
99
self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory,
1010
FakeReadCause, Local, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef,
11-
ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
11+
ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm,
1212
};
13-
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
14-
use rustc_span::source_map::DesugaringKind;
15-
use rustc_span::Span;
13+
use rustc_middle::ty::{self, suggest_constraining_type_param, Instance, Ty};
14+
use rustc_span::{source_map::DesugaringKind, symbol::sym, Span};
1615

1716
use crate::dataflow::drop_flag_effects;
1817
use crate::dataflow::indexes::{MoveOutIndex, MovePathIndex};
@@ -1543,9 +1542,43 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15431542
None,
15441543
);
15451544

1545+
self.explain_deref_coercion(loan, &mut err);
1546+
15461547
err.buffer(&mut self.errors_buffer);
15471548
}
15481549

1550+
fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut DiagnosticBuilder<'_>) {
1551+
let tcx = self.infcx.tcx;
1552+
if let (
1553+
Some(Terminator { kind: TerminatorKind::Call { from_hir_call: false, .. }, .. }),
1554+
Some((method_did, method_substs)),
1555+
) = (
1556+
&self.body[loan.reserve_location.block].terminator,
1557+
crate::util::find_self_call(
1558+
tcx,
1559+
self.body,
1560+
loan.assigned_place.local,
1561+
loan.reserve_location.block,
1562+
),
1563+
) {
1564+
if tcx.is_diagnostic_item(sym::deref_method, method_did) {
1565+
let deref_target =
1566+
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
1567+
Instance::resolve(tcx, self.param_env, deref_target, method_substs)
1568+
.transpose()
1569+
});
1570+
if let Some(Ok(instance)) = deref_target {
1571+
let deref_target_ty = instance.ty(tcx, self.param_env);
1572+
err.note(&format!(
1573+
"borrow occurs due to deref coercion to `{}`",
1574+
deref_target_ty
1575+
));
1576+
err.span_note(tcx.def_span(instance.def_id()), "deref defined here");
1577+
}
1578+
}
1579+
}
1580+
}
1581+
15491582
/// Reports an illegal reassignment; for example, an assignment to
15501583
/// (part of) a non-`mut` local that occurs potentially after that
15511584
/// local has already been initialized. `place` is the path being

compiler/rustc_mir/src/util/graphviz.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use gsgdt::GraphvizSettings;
22
use rustc_graphviz as dot;
33
use rustc_hir::def_id::DefId;
44
use rustc_middle::mir::*;
5-
use rustc_middle::ty::TyCtxt;
5+
use rustc_middle::ty::{self, TyCtxt};
66
use std::fmt::Debug;
77
use std::io::{self, Write};
88

@@ -16,14 +16,27 @@ where
1616
{
1717
let def_ids = dump_mir_def_ids(tcx, single);
1818

19-
let use_subgraphs = def_ids.len() > 1;
19+
let mirs =
20+
def_ids
21+
.iter()
22+
.flat_map(|def_id| {
23+
if tcx.is_const_fn_raw(*def_id) {
24+
vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)]
25+
} else {
26+
vec![tcx.instance_mir(ty::InstanceDef::Item(ty::WithOptConstParam::unknown(
27+
*def_id,
28+
)))]
29+
}
30+
})
31+
.collect::<Vec<_>>();
32+
33+
let use_subgraphs = mirs.len() > 1;
2034
if use_subgraphs {
2135
writeln!(w, "digraph __crate__ {{")?;
2236
}
2337

24-
for def_id in def_ids {
25-
let body = &tcx.optimized_mir(def_id);
26-
write_mir_fn_graphviz(tcx, body, use_subgraphs, w)?;
38+
for mir in mirs {
39+
write_mir_fn_graphviz(tcx, mir, use_subgraphs, w)?;
2740
}
2841

2942
if use_subgraphs {

compiler/rustc_parse/src/parser/item.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1475,15 +1475,7 @@ impl<'a> Parser<'a> {
14751475
let vstr = pprust::vis_to_string(vis);
14761476
let vstr = vstr.trim_end();
14771477
if macro_rules {
1478-
let msg = format!("can't qualify macro_rules invocation with `{}`", vstr);
1479-
self.struct_span_err(vis.span, &msg)
1480-
.span_suggestion(
1481-
vis.span,
1482-
"try exporting the macro",
1483-
"#[macro_export]".to_owned(),
1484-
Applicability::MaybeIncorrect, // speculative
1485-
)
1486-
.emit();
1478+
self.sess.gated_spans.gate(sym::pub_macro_rules, vis.span);
14871479
} else {
14881480
self.struct_span_err(vis.span, "can't qualify macro invocation with `pub`")
14891481
.span_suggestion(

compiler/rustc_passes/src/dead.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,6 @@ fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
3737
)
3838
}
3939

40-
fn base_expr<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
41-
loop {
42-
match expr.kind {
43-
hir::ExprKind::Field(base, ..) => expr = base,
44-
_ => return expr,
45-
}
46-
}
47-
}
48-
4940
struct MarkSymbolVisitor<'tcx> {
5041
worklist: Vec<hir::HirId>,
5142
tcx: TyCtxt<'tcx>,
@@ -143,6 +134,22 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
143134
}
144135
}
145136

137+
fn handle_assign(&mut self, expr: &'tcx hir::Expr<'tcx>) {
138+
if self
139+
.typeck_results()
140+
.expr_adjustments(expr)
141+
.iter()
142+
.any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(_)))
143+
{
144+
self.visit_expr(expr);
145+
} else if let hir::ExprKind::Field(base, ..) = expr.kind {
146+
// Ignore write to field
147+
self.handle_assign(base);
148+
} else {
149+
self.visit_expr(expr);
150+
}
151+
}
152+
146153
fn handle_field_pattern_match(
147154
&mut self,
148155
lhs: &hir::Pat<'_>,
@@ -272,8 +279,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
272279
self.lookup_and_handle_method(expr.hir_id);
273280
}
274281
hir::ExprKind::Assign(ref left, ref right, ..) => {
275-
// Ignore write to field
276-
self.visit_expr(base_expr(left));
282+
self.handle_assign(left);
277283
self.visit_expr(right);
278284
return;
279285
}

compiler/rustc_passes/src/hir_stats.rs

+5
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
114114
self.visit_impl_item(nested_impl_item)
115115
}
116116

117+
fn visit_nested_foreign_item(&mut self, id: hir::ForeignItemId) {
118+
let nested_foreign_item = self.krate.unwrap().foreign_item(id);
119+
self.visit_foreign_item(nested_foreign_item);
120+
}
121+
117122
fn visit_nested_body(&mut self, body_id: hir::BodyId) {
118123
let nested_body = self.krate.unwrap().body(body_id);
119124
self.visit_body(nested_body)

compiler/rustc_resolve/src/build_reduced_graph.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1230,13 +1230,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
12301230
};
12311231

12321232
let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id.to_def_id());
1233+
let is_macro_export = self.r.session.contains_name(&item.attrs, sym::macro_export);
12331234
self.r.macro_map.insert(def_id.to_def_id(), ext);
12341235
self.r.local_macro_def_scopes.insert(def_id, parent_scope.module);
12351236

1236-
if macro_rules {
1237+
if macro_rules && matches!(item.vis.kind, ast::VisibilityKind::Inherited) {
12371238
let ident = ident.normalize_to_macros_2_0();
12381239
self.r.macro_names.insert(ident);
1239-
let is_macro_export = self.r.session.contains_name(&item.attrs, sym::macro_export);
12401240
let vis = if is_macro_export {
12411241
ty::Visibility::Public
12421242
} else {
@@ -1261,6 +1261,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
12611261
}),
12621262
))
12631263
} else {
1264+
if is_macro_export {
1265+
let what = if macro_rules { "`macro_rules` with `pub`" } else { "`macro` items" };
1266+
let msg = format!("`#[macro_export]` cannot be used on {what}");
1267+
self.r.session.span_err(item.span, &msg);
1268+
}
12641269
let module = parent_scope.module;
12651270
let vis = match item.kind {
12661271
// Visibilities must not be resolved non-speculatively twice

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ symbols! {
560560
format_args,
561561
format_args_capture,
562562
format_args_nl,
563+
format_macro,
563564
freeze,
564565
freg,
565566
frem_fast,
@@ -880,6 +881,7 @@ symbols! {
880881
ptr_guaranteed_eq,
881882
ptr_guaranteed_ne,
882883
ptr_offset_from,
884+
pub_macro_rules,
883885
pub_restricted,
884886
pure,
885887
pushpop_unsafe,

library/alloc/src/macros.rs

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ macro_rules! vec {
107107
/// ```
108108
#[macro_export]
109109
#[stable(feature = "rust1", since = "1.0.0")]
110+
#[cfg_attr(not(test), rustc_diagnostic_item = "format_macro")]
110111
macro_rules! format {
111112
($($arg:tt)*) => {{
112113
let res = $crate::fmt::format($crate::__export::format_args!($($arg)*));

library/core/tests/atomic.rs

+4
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ fn uint_xor() {
6161

6262
#[test]
6363
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
64+
#[cfg_attr(miri, ignore)] // FIXME: Miri does not support atomic_min
6465
fn uint_min() {
6566
let x = AtomicUsize::new(0xf731);
6667
assert_eq!(x.fetch_min(0x137f, SeqCst), 0xf731);
@@ -71,6 +72,7 @@ fn uint_min() {
7172

7273
#[test]
7374
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
75+
#[cfg_attr(miri, ignore)] // FIXME: Miri does not support atomic_max
7476
fn uint_max() {
7577
let x = AtomicUsize::new(0x137f);
7678
assert_eq!(x.fetch_max(0xf731, SeqCst), 0x137f);
@@ -109,6 +111,7 @@ fn int_xor() {
109111

110112
#[test]
111113
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
114+
#[cfg_attr(miri, ignore)] // FIXME: Miri does not support atomic_min
112115
fn int_min() {
113116
let x = AtomicIsize::new(0xf731);
114117
assert_eq!(x.fetch_min(0x137f, SeqCst), 0xf731);
@@ -119,6 +122,7 @@ fn int_min() {
119122

120123
#[test]
121124
#[cfg(any(not(target_arch = "arm"), target_os = "linux"))] // Missing intrinsic in compiler-builtins
125+
#[cfg_attr(miri, ignore)] // FIXME: Miri does not support atomic_max
122126
fn int_max() {
123127
let x = AtomicIsize::new(0x137f);
124128
assert_eq!(x.fetch_max(0xf731, SeqCst), 0x137f);

src/librustdoc/clean/auto_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
4141
) -> Option<Item> {
4242
let tcx = self.cx.tcx;
4343
let trait_ref = ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, &[]) };
44-
if !self.cx.generated_synthetics.borrow_mut().insert((ty, trait_def_id)) {
44+
if !self.cx.generated_synthetics.insert((ty, trait_def_id)) {
4545
debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref);
4646
return None;
4747
}

0 commit comments

Comments
 (0)