Skip to content

Commit

Permalink
Auto merge of #99592 - Dylan-DPC:rollup-xlw4wax, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #98174 (Rename `<*{mut,const} T>::as_{const,mut}` to `cast_`)
 - #98868 (Fix unreachable coverage generation for inlined functions)
 - #99393 (feat: omit suffixes in const generics (e.g. `1_i32`))
 - #99423 (Group CSS font rule)
 - #99539 (Improve suggestions for returning binding)
 - #99579 (Add same warning to Result::expect as Result::unwrap)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jul 22, 2022
2 parents aa01891 + 5df3b98 commit e7a9c11
Show file tree
Hide file tree
Showing 71 changed files with 949 additions and 706 deletions.
7 changes: 2 additions & 5 deletions compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@ use super::FunctionCx;
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn codegen_coverage(&self, bx: &mut Bx, coverage: Coverage, scope: SourceScope) {
// Determine the instance that coverage data was originally generated for.
let scope_data = &self.mir.source_scopes[scope];
let instance = if let Some((inlined_instance, _)) = scope_data.inlined {
self.monomorphize(inlined_instance)
} else if let Some(inlined_scope) = scope_data.inlined_parent_scope {
self.monomorphize(self.mir.source_scopes[inlined_scope].inlined.unwrap().0)
let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
self.monomorphize(inlined)
} else {
self.instance
};
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,16 @@ pub struct Block<'hir> {
pub targeted_by_break: bool,
}

impl<'hir> Block<'hir> {
pub fn innermost_block(&self) -> &Block<'hir> {
let mut block = self;
while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
block = inner_block;
}
block
}
}

#[derive(Debug, HashStable_Generic)]
pub struct Pat<'hir> {
#[stable_hasher(ignore)]
Expand Down
539 changes: 422 additions & 117 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1662,6 +1662,22 @@ impl SourceScope {
ClearCrossCrate::Clear => None,
}
}

/// The instance this source scope was inlined from, if any.
#[inline]
pub fn inlined_instance<'tcx>(
self,
source_scopes: &IndexVec<SourceScope, SourceScopeData<'tcx>>,
) -> Option<ty::Instance<'tcx>> {
let scope_data = &source_scopes[self];
if let Some((inlined_instance, _)) = scope_data.inlined {
Some(inlined_instance)
} else if let Some(inlined_scope) = scope_data.inlined_parent_scope {
Some(source_scopes[inlined_scope].inlined.unwrap().0)
} else {
None
}
}
}

#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
Expand Down
23 changes: 14 additions & 9 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ pub enum ObligationCauseCode<'tcx> {
ConstPatternStructural,

/// Computing common supertype in an if expression
IfExpression(Box<IfExpressionCause>),
IfExpression(Box<IfExpressionCause<'tcx>>),

/// Computing common supertype of an if expression with no else counter-part
IfExpressionWithNoElse,
Expand Down Expand Up @@ -488,22 +488,27 @@ impl<'tcx> ty::Lift<'tcx> for StatementAsExpression {

#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
pub struct MatchExpressionArmCause<'tcx> {
pub arm_block_id: Option<hir::HirId>,
pub arm_ty: Ty<'tcx>,
pub arm_span: Span,
pub prior_arm_block_id: Option<hir::HirId>,
pub prior_arm_ty: Ty<'tcx>,
pub prior_arm_span: Span,
pub scrut_span: Span,
pub semi_span: Option<(Span, StatementAsExpression)>,
pub source: hir::MatchSource,
pub prior_arms: Vec<Span>,
pub last_ty: Ty<'tcx>,
pub scrut_hir_id: hir::HirId,
pub opt_suggest_box_span: Option<Span>,
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct IfExpressionCause {
pub then: Span,
pub else_sp: Span,
pub outer: Option<Span>,
pub semicolon: Option<(Span, StatementAsExpression)>,
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Lift, TypeFoldable, TypeVisitable)]
pub struct IfExpressionCause<'tcx> {
pub then_id: hir::HirId,
pub else_id: hir::HirId,
pub then_ty: Ty<'tcx>,
pub else_ty: Ty<'tcx>,
pub outer_span: Option<Span>,
pub opt_suggest_box_span: Option<Span>,
}

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ impl<N: fmt::Debug> fmt::Debug for traits::ImplSourceConstDestructData<N> {
// Lift implementations

TrivialTypeTraversalAndLiftImpls! {
super::IfExpressionCause,
super::ImplSourceDiscriminantKindData,
super::ImplSourcePointeeData,
}
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1729,7 +1729,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> {
}

fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
self.pretty_print_const(ct, true)
self.pretty_print_const(ct, false)
}

fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
Expand Down
78 changes: 43 additions & 35 deletions compiler/rustc_mir_transform/src/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
//! return.
use crate::MirPass;
use rustc_data_structures::fx::FxHashSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::mir::coverage::*;
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
Expand Down Expand Up @@ -267,7 +268,8 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
return;
}

let basic_blocks = body.basic_blocks_mut();
let basic_blocks = body.basic_blocks.as_mut();
let source_scopes = &body.source_scopes;
let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
let mut used_blocks = 0;
for alive_index in reachable.iter() {
Expand All @@ -282,7 +284,7 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
}

if tcx.sess.instrument_coverage() {
save_unreachable_coverage(basic_blocks, used_blocks);
save_unreachable_coverage(basic_blocks, source_scopes, used_blocks);
}

basic_blocks.raw.truncate(used_blocks);
Expand Down Expand Up @@ -311,56 +313,62 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
/// `Unreachable` coverage statements. These are non-executable statements whose
/// code regions are still recorded in the coverage map, representing regions
/// with `0` executions.
///
/// If there are no live `Counter` `Coverage` statements remaining, we remove
/// dead `Coverage` statements along with the dead blocks. Since at least one
/// counter per function is required by LLVM (and necessary, to add the
/// `function_hash` to the counter's call to the LLVM intrinsic
/// `instrprof.increment()`).
///
/// The `generator::StateTransform` MIR pass and MIR inlining can create
/// atypical conditions, where all live `Counter`s are dropped from the MIR.
///
/// With MIR inlining we can have coverage counters belonging to different
/// instances in a single body, so the strategy described above is applied to
/// coverage counters from each instance individually.
fn save_unreachable_coverage(
basic_blocks: &mut IndexVec<BasicBlock, BasicBlockData<'_>>,
source_scopes: &IndexVec<SourceScope, SourceScopeData<'_>>,
first_dead_block: usize,
) {
let has_live_counters = basic_blocks.raw[0..first_dead_block].iter().any(|live_block| {
live_block.statements.iter().any(|statement| {
if let StatementKind::Coverage(coverage) = &statement.kind {
matches!(coverage.kind, CoverageKind::Counter { .. })
} else {
false
}
})
});
if !has_live_counters {
// If there are no live `Counter` `Coverage` statements anymore, don't
// move dead coverage to the `START_BLOCK`. Just allow the dead
// `Coverage` statements to be dropped with the dead blocks.
//
// The `generator::StateTransform` MIR pass can create atypical
// conditions, where all live `Counter`s are dropped from the MIR.
//
// At least one Counter per function is required by LLVM (and necessary,
// to add the `function_hash` to the counter's call to the LLVM
// intrinsic `instrprof.increment()`).
// Identify instances that still have some live coverage counters left.
let mut live = FxHashSet::default();
for basic_block in &basic_blocks.raw[0..first_dead_block] {
for statement in &basic_block.statements {
let StatementKind::Coverage(coverage) = &statement.kind else { continue };
let CoverageKind::Counter { .. } = coverage.kind else { continue };
let instance = statement.source_info.scope.inlined_instance(source_scopes);
live.insert(instance);
}
}

if live.is_empty() {
return;
}

// Retain coverage info for dead blocks, so coverage reports will still
// report `0` executions for the uncovered code regions.
let mut dropped_coverage = Vec::new();
for dead_block in basic_blocks.raw[first_dead_block..].iter() {
for statement in dead_block.statements.iter() {
if let StatementKind::Coverage(coverage) = &statement.kind {
if let Some(code_region) = &coverage.code_region {
dropped_coverage.push((statement.source_info, code_region.clone()));
}
// Retain coverage for instances that still have some live counters left.
let mut retained_coverage = Vec::new();
for dead_block in &basic_blocks.raw[first_dead_block..] {
for statement in &dead_block.statements {
let StatementKind::Coverage(coverage) = &statement.kind else { continue };
let Some(code_region) = &coverage.code_region else { continue };
let instance = statement.source_info.scope.inlined_instance(source_scopes);
if live.contains(&instance) {
retained_coverage.push((statement.source_info, code_region.clone()));
}
}
}

let start_block = &mut basic_blocks[START_BLOCK];
for (source_info, code_region) in dropped_coverage {
start_block.statements.push(Statement {
start_block.statements.extend(retained_coverage.into_iter().map(
|(source_info, code_region)| Statement {
source_info,
kind: StatementKind::Coverage(Box::new(Coverage {
kind: CoverageKind::Unreachable,
code_region: Some(code_region),
})),
})
}
},
));
}

pub struct SimplifyLocals;
Expand Down
12 changes: 9 additions & 3 deletions compiler/rustc_monomorphize/src/partitioning/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ mod merging;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync;
use rustc_hir::def_id::DefIdSet;
use rustc_middle::mir;
use rustc_middle::mir::mono::MonoItem;
use rustc_middle::mir::mono::{CodegenUnit, Linkage};
use rustc_middle::ty::print::with_no_trimmed_paths;
Expand Down Expand Up @@ -479,9 +480,14 @@ fn codegened_and_inlined_items<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx DefIdSe
if !visited.insert(did) {
continue;
}
for scope in &tcx.instance_mir(instance.def).source_scopes {
if let Some((ref inlined, _)) = scope.inlined {
result.insert(inlined.def_id());
let body = tcx.instance_mir(instance.def);
for block in body.basic_blocks() {
for statement in &block.statements {
let mir::StatementKind::Coverage(_) = statement.kind else { continue };
let scope = statement.source_info.scope;
if let Some(inlined) = scope.inlined_instance(&body.source_scopes) {
result.insert(inlined.def_id());
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use rustc_hir::intravisit::Visitor;
use rustc_hir::GenericParam;
use rustc_hir::Item;
use rustc_hir::Node;
use rustc_infer::infer::error_reporting::same_type_modulo_infer;
use rustc_infer::traits::TraitEngine;
use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
Expand Down Expand Up @@ -640,7 +639,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
if expected.len() == 1 { "" } else { "s" },
)
);
} else if !same_type_modulo_infer(given_ty, expected_ty) {
} else if !self.same_type_modulo_infer(given_ty, expected_ty) {
// Print type mismatch
let (expected_args, given_args) =
self.cmp(given_ty, expected_ty);
Expand Down
Loading

0 comments on commit e7a9c11

Please sign in to comment.