Skip to content

Rollup of 5 pull requests #82811

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 25 commits into from
Closed
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ae494d1
Detect match arm body without braces
estebank Feb 26, 2021
e2e9e49
Extract mir_opt_level to a method and use Option to be able to know i…
spastorino Mar 3, 2021
c86b7b4
For better consistency change mir_opt_level <= 1 to < 2
spastorino Mar 3, 2021
b5da6f8
Bump all mir_opt_level 3 to 4
spastorino Mar 3, 2021
4bf42c8
Bump all mir_opt_level 2 to 3
spastorino Mar 3, 2021
10d0109
Make mir_opt_level default to 2 for optimized levels
spastorino Mar 3, 2021
38ec6be
Make clippy set mir_opt_level using Option
spastorino Mar 4, 2021
0f9fdba
Bump mir-opt-level from 3 to 4 in tests
spastorino Mar 4, 2021
0550a6f
Bump mir-opt-level from 2 to 3 in tests
spastorino Mar 4, 2021
5a064e8
Fix rustc_driver self text and bump the mir_opt_level
spastorino Mar 4, 2021
cbb40e1
Bump one missing mir_opt_level
spastorino Mar 4, 2021
6f32e3e
Add new edition 2021 link: INVALID_DOC_ATTRIBUTE
GuillaumeGomez Mar 3, 2021
a66bf52
Add extra check for #[doc(test(...)] attribute
GuillaumeGomez Mar 2, 2021
85c3d10
Add tests for #[doc(test(...)] check
GuillaumeGomez Mar 2, 2021
55cec90
Also use INVALID_DOC_ATTRIBUTE for "unknown doc attribute" warnings
GuillaumeGomez Mar 4, 2021
18fb025
Fix MIR optimization level description
spastorino Mar 5, 2021
cb9b10c
Update tests names to start with `issue-`
henryboisdequin Mar 5, 2021
a11e87e
Make invalid_doc_attribute lint plural
GuillaumeGomez Mar 5, 2021
f879ecc
Make ItemKind::ExternCrate looks like hir::ItemKind::ExternCrate to m…
GuillaumeGomez Mar 5, 2021
286a357
Refactor from_clean_item_kind to improve ExternCrateItem handling
GuillaumeGomez Mar 5, 2021
11dddf2
Rollup merge of #80845 - GuillaumeGomez:item-kind-transition, r=jyn514
GuillaumeGomez Mar 5, 2021
0dd9066
Rollup merge of #82708 - GuillaumeGomez:doc-test-attr-check, r=Manish…
GuillaumeGomez Mar 5, 2021
4ec6b35
Rollup merge of #82714 - estebank:missing-braces, r=oli-obk
GuillaumeGomez Mar 5, 2021
be6d958
Rollup merge of #82736 - spastorino:mir-opt-level-perf-changes, r=oli…
GuillaumeGomez Mar 5, 2021
70d6fed
Rollup merge of #82797 - henryboisdequin:name-issue-num, r=Xanewok
GuillaumeGomez Mar 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
@@ -566,7 +566,7 @@ fn test_debugging_options_tracking_hash() {
tracked!(link_only, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(mir_emit_retag, true);
tracked!(mir_opt_level, 3);
tracked!(mir_opt_level, Some(4));
tracked!(mutable_noalias, true);
tracked!(new_llvm_pass_manager, true);
tracked!(no_codegen, true);
30 changes: 30 additions & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
@@ -3059,3 +3059,33 @@ declare_lint! {
Allow,
"No declared ABI for extern declaration"
}

declare_lint! {
/// The `invalid_doc_attributes` lint detects when the `#[doc(...)]` is
/// misused.
///
/// ### Example
///
/// ```rust,compile_fail
/// #![deny(warnings)]
///
/// pub mod submodule {
/// #![doc(test(no_crate_inject))]
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// Previously, there were very like checks being performed on `#[doc(..)]`
/// unlike the other attributes. It'll now catch all the issues that it
/// silently ignored previously.
pub INVALID_DOC_ATTRIBUTES,
Warn,
"detects invalid `#[doc(...)]` attributes",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #82730 <https://github.com/rust-lang/rust/issues/82730>",
edition: None,
};
}
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/const_goto.rs
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ pub struct ConstGoto;

impl<'tcx> MirPass<'tcx> for ConstGoto {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
if tcx.sess.mir_opt_level() < 4 {
return;
}
trace!("Running ConstGoto on {:?}", body.source);
12 changes: 6 additions & 6 deletions compiler/rustc_mir/src/transform/const_prop.rs
Original file line number Diff line number Diff line change
@@ -725,7 +725,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
return None;
}

if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 3 {
if self.tcx.sess.mir_opt_level() >= 4 {
self.eval_rvalue_with_identities(rvalue, place)
} else {
self.use_ecx(|this| this.ecx.eval_rvalue_into_place(rvalue, place))
@@ -903,7 +903,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {

/// Returns `true` if and only if this `op` should be const-propagated into.
fn should_const_prop(&mut self, op: &OpTy<'tcx>) -> bool {
let mir_opt_level = self.tcx.sess.opts.debugging_opts.mir_opt_level;
let mir_opt_level = self.tcx.sess.mir_opt_level();

if mir_opt_level == 0 {
return false;
@@ -1071,9 +1071,9 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
self.super_operand(operand, location);

// Only const prop copies and moves on `mir_opt_level=2` as doing so
// Only const prop copies and moves on `mir_opt_level=3` as doing so
// currently slightly increases compile time in some cases.
if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
if self.tcx.sess.mir_opt_level() >= 3 {
self.propagate_operand(operand)
}
}
@@ -1253,7 +1253,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
TerminatorKind::SwitchInt { ref mut discr, .. } => {
// FIXME: This is currently redundant with `visit_operand`, but sadly
// always visiting operands currently causes a perf regression in LLVM codegen, so
// `visit_operand` currently only runs for propagates places for `mir_opt_level=3`.
// `visit_operand` currently only runs for propagates places for `mir_opt_level=4`.
self.propagate_operand(discr)
}
// None of these have Operands to const-propagate.
@@ -1272,7 +1272,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
// Every argument in our function calls have already been propagated in `visit_operand`.
//
// NOTE: because LLVM codegen gives slight performance regressions with it, so this is
// gated on `mir_opt_level=2`.
// gated on `mir_opt_level=3`.
TerminatorKind::Call { .. } => {}
}

2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/deduplicate_blocks.rs
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ pub struct DeduplicateBlocks;

impl<'tcx> MirPass<'tcx> for DeduplicateBlocks {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
if tcx.sess.mir_opt_level() < 4 {
return;
}
debug!("Running DeduplicateBlocks on `{:?}`", body.source);
4 changes: 2 additions & 2 deletions compiler/rustc_mir/src/transform/dest_prop.rs
Original file line number Diff line number Diff line change
@@ -127,9 +127,9 @@ pub struct DestinationPropagation;

impl<'tcx> MirPass<'tcx> for DestinationPropagation {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove
// Only run at mir-opt-level=3 or higher for now (we don't fix up debuginfo and remove
// storage statements at the moment).
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
if tcx.sess.mir_opt_level() < 3 {
return;
}

2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/early_otherwise_branch.rs
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ pub struct EarlyOtherwiseBranch;

impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 2 {
if tcx.sess.mir_opt_level() < 3 {
return;
}
trace!("running EarlyOtherwiseBranch on {:?}", body.source);
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ crate fn is_enabled(tcx: TyCtxt<'_>) -> bool {
return enabled;
}

tcx.sess.opts.debugging_opts.mir_opt_level >= 2
tcx.sess.mir_opt_level() >= 3
}

impl<'tcx> MirPass<'tcx> for Inline {
2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/match_branches.rs
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ pub struct MatchBranchSimplification;

impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
if tcx.sess.mir_opt_level() < 3 {
return;
}

2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/mod.rs
Original file line number Diff line number Diff line change
@@ -475,7 +475,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
}

fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mir_opt_level = tcx.sess.opts.debugging_opts.mir_opt_level;
let mir_opt_level = tcx.sess.mir_opt_level();

// Lowering generator control-flow and variables has to happen before we do anything else
// to them. We run some optimizations before that, because they may be harder to do on the state
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ pub struct MultipleReturnTerminators;

impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
if tcx.sess.mir_opt_level() < 4 {
return;
}

2 changes: 1 addition & 1 deletion compiler/rustc_mir/src/transform/nrvo.rs
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ pub struct RenameReturnPlace;

impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
if tcx.sess.mir_opt_level() == 0 {
return;
}

4 changes: 2 additions & 2 deletions compiler/rustc_mir/src/transform/unreachable_prop.rs
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ pub struct UnreachablePropagation;

impl MirPass<'_> for UnreachablePropagation {
fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 3 {
// Enable only under -Zmir-opt-level=3 as in some cases (check the deeply-nested-opt
if tcx.sess.mir_opt_level() < 4 {
// Enable only under -Zmir-opt-level=4 as in some cases (check the deeply-nested-opt
// perf benchmark) LLVM may spend quite a lot of time optimizing the generated code.
return;
}
111 changes: 111 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
@@ -1973,6 +1973,102 @@ impl<'a> Parser<'a> {
Ok(self.mk_expr(lo.to(hi), ExprKind::Match(scrutinee, arms), attrs))
}

/// Attempt to recover from match arm body with statements and no surrounding braces.
fn parse_arm_body_missing_braces(
&mut self,
first_expr: &P<Expr>,
arrow_span: Span,
) -> Option<P<Expr>> {
if self.token.kind != token::Semi {
return None;
}
let start_snapshot = self.clone();
let semi_sp = self.token.span;
self.bump(); // `;`
let mut stmts =
vec![self.mk_stmt(first_expr.span, ast::StmtKind::Expr(first_expr.clone()))];
let err = |this: &mut Parser<'_>, stmts: Vec<ast::Stmt>| {
let span = stmts[0].span.to(stmts[stmts.len() - 1].span);
let mut err = this.struct_span_err(span, "`match` arm body without braces");
let (these, s, are) =
if stmts.len() > 1 { ("these", "s", "are") } else { ("this", "", "is") };
err.span_label(
span,
&format!(
"{these} statement{s} {are} not surrounded by a body",
these = these,
s = s,
are = are
),
);
err.span_label(arrow_span, "while parsing the `match` arm starting here");
if stmts.len() > 1 {
err.multipart_suggestion(
&format!("surround the statement{} with a body", s),
vec![
(span.shrink_to_lo(), "{ ".to_string()),
(span.shrink_to_hi(), " }".to_string()),
],
Applicability::MachineApplicable,
);
} else {
err.span_suggestion(
semi_sp,
"use a comma to end a `match` arm expression",
",".to_string(),
Applicability::MachineApplicable,
);
}
err.emit();
this.mk_expr_err(span)
};
// We might have either a `,` -> `;` typo, or a block without braces. We need
// a more subtle parsing strategy.
loop {
if self.token.kind == token::CloseDelim(token::Brace) {
// We have reached the closing brace of the `match` expression.
return Some(err(self, stmts));
}
if self.token.kind == token::Comma {
*self = start_snapshot;
return None;
}
let pre_pat_snapshot = self.clone();
match self.parse_pat_no_top_alt(None) {
Ok(_pat) => {
if self.token.kind == token::FatArrow {
// Reached arm end.
*self = pre_pat_snapshot;
return Some(err(self, stmts));
}
}
Err(mut err) => {
err.cancel();
}
}

*self = pre_pat_snapshot;
match self.parse_stmt_without_recovery(true, ForceCollect::No) {
// Consume statements for as long as possible.
Ok(Some(stmt)) => {
stmts.push(stmt);
}
Ok(None) => {
*self = start_snapshot;
break;
}
// We couldn't parse either yet another statement missing it's
// enclosing block nor the next arm's pattern or closing brace.
Err(mut stmt_err) => {
stmt_err.cancel();
*self = start_snapshot;
break;
}
}
}
None
}

pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> {
let attrs = self.parse_outer_attributes()?;
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
@@ -2007,6 +2103,21 @@ impl<'a> Parser<'a> {

if require_comma {
let sm = this.sess.source_map();
if let Some(body) = this.parse_arm_body_missing_braces(&expr, arrow_span) {
let span = body.span;
return Ok((
ast::Arm {
attrs,
pat,
guard,
body,
span,
id: DUMMY_NODE_ID,
is_placeholder: false,
},
TrailingToken::None,
));
}
this.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]).map_err(
|mut err| {
match (sm.span_to_lines(expr.span), sm.span_to_lines(arm_start_span)) {
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ impl<'a> Parser<'a> {

/// If `force_capture` is true, forces collection of tokens regardless of whether
/// or not we have attributes
fn parse_stmt_without_recovery(
crate fn parse_stmt_without_recovery(
&mut self,
capture_semi: bool,
force_collect: ForceCollect,
26 changes: 19 additions & 7 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,9 @@ use rustc_hir::{
self, FnSig, ForeignItem, ForeignItemKind, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID,
};
use rustc_hir::{MethodKind, Target};
use rustc_session::lint::builtin::{CONFLICTING_REPR_HINTS, UNUSED_ATTRIBUTES};
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES,
};
use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
@@ -544,6 +546,21 @@ impl CheckAttrVisitor<'tcx> {
{
return false;
}
} else if meta.has_name(sym::test) {
if CRATE_HIR_ID != hir_id {
self.tcx.struct_span_lint_hir(
INVALID_DOC_ATTRIBUTES,
hir_id,
meta.span(),
|lint| {
lint.build(
"`#![doc(test(...)]` is only allowed as a crate level attribute"
)
.emit();
},
);
return false;
}
} else if let Some(i_meta) = meta.meta_item() {
if ![
sym::cfg,
@@ -568,19 +585,14 @@ impl CheckAttrVisitor<'tcx> {
.any(|m| i_meta.has_name(*m))
{
self.tcx.struct_span_lint_hir(
UNUSED_ATTRIBUTES,
INVALID_DOC_ATTRIBUTES,
hir_id,
i_meta.span,
|lint| {
lint.build(&format!(
"unknown `doc` attribute `{}`",
i_meta.name_or_empty()
))
.warn(
"this was previously accepted by the compiler but is \
being phased out; it will become a hard error in \
a future release!",
)
.emit();
},
);
Loading