Skip to content

Commit

Permalink
Auto merge of rust-lang#95382 - Dylan-DPC:rollup-bebyfd1, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - rust-lang#94939 (diagnostics: suggest missing comma in bad FRU syntax)
 - rust-lang#95120 (Implement `apply_switch_int_edge_effects` for backward analyses)
 - rust-lang#95364 (Add long error explanation for E0667)
 - rust-lang#95366 (Remove test files with duplicated checksums)
 - rust-lang#95368 (Fix typo in `String::try_reserve_exact` docs)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 27, 2022
2 parents ab0c2e1 + eca2531 commit 6252304
Show file tree
Hide file tree
Showing 23 changed files with 287 additions and 80 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ E0663: include_str!("./error_codes/E0663.md"),
E0664: include_str!("./error_codes/E0664.md"),
E0665: include_str!("./error_codes/E0665.md"),
E0666: include_str!("./error_codes/E0666.md"),
E0667: include_str!("./error_codes/E0667.md"),
E0668: include_str!("./error_codes/E0668.md"),
E0669: include_str!("./error_codes/E0669.md"),
E0670: include_str!("./error_codes/E0670.md"),
Expand Down Expand Up @@ -633,7 +634,6 @@ E0787: include_str!("./error_codes/E0787.md"),
// attribute
E0640, // infer outlives requirements
// E0645, // trait aliases not finished
E0667, // `impl Trait` in projections
// E0694, // an unknown tool name found in scoped attributes
// E0702, // replaced with a generic attribute input check
// E0707, // multiple elided lifetimes used in arguments of `async fn`
Expand Down
18 changes: 18 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0667.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
`impl Trait` is not allowed in path parameters.

Erroneous code example:

```compile_fail,E0667
fn some_fn(mut x: impl Iterator) -> <impl Iterator>::Item { // error!
x.next().unwrap()
}
```

You cannot use `impl Trait` in path parameters. If you want something
equivalent, you can do this instead:

```
fn some_fn<T: Iterator>(mut x: T) -> T::Item { // ok!
x.next().unwrap()
}
```
13 changes: 13 additions & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ use std::{iter, mem, option};
use self::graph_cyclic_cache::GraphIsCyclicCache;
use self::predecessors::{PredecessorCache, Predecessors};
pub use self::query::*;
use self::switch_sources::{SwitchSourceCache, SwitchSources};

pub mod coverage;
mod generic_graph;
Expand All @@ -58,6 +59,7 @@ mod predecessors;
pub mod pretty;
mod query;
pub mod spanview;
mod switch_sources;
pub mod tcx;
pub mod terminator;
pub use terminator::*;
Expand Down Expand Up @@ -296,6 +298,7 @@ pub struct Body<'tcx> {
pub is_polymorphic: bool,

predecessor_cache: PredecessorCache,
switch_source_cache: SwitchSourceCache,
is_cyclic: GraphIsCyclicCache,

pub tainted_by_errors: Option<ErrorGuaranteed>,
Expand Down Expand Up @@ -344,6 +347,7 @@ impl<'tcx> Body<'tcx> {
required_consts: Vec::new(),
is_polymorphic: false,
predecessor_cache: PredecessorCache::new(),
switch_source_cache: SwitchSourceCache::new(),
is_cyclic: GraphIsCyclicCache::new(),
tainted_by_errors,
};
Expand Down Expand Up @@ -372,6 +376,7 @@ impl<'tcx> Body<'tcx> {
var_debug_info: Vec::new(),
is_polymorphic: false,
predecessor_cache: PredecessorCache::new(),
switch_source_cache: SwitchSourceCache::new(),
is_cyclic: GraphIsCyclicCache::new(),
tainted_by_errors: None,
};
Expand All @@ -392,6 +397,7 @@ impl<'tcx> Body<'tcx> {
// FIXME: Use a finer-grained API for this, so only transformations that alter terminators
// invalidate the caches.
self.predecessor_cache.invalidate();
self.switch_source_cache.invalidate();
self.is_cyclic.invalidate();
&mut self.basic_blocks
}
Expand All @@ -401,6 +407,7 @@ impl<'tcx> Body<'tcx> {
&mut self,
) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
self.predecessor_cache.invalidate();
self.switch_source_cache.invalidate();
self.is_cyclic.invalidate();
(&mut self.basic_blocks, &mut self.local_decls)
}
Expand All @@ -414,6 +421,7 @@ impl<'tcx> Body<'tcx> {
&mut Vec<VarDebugInfo<'tcx>>,
) {
self.predecessor_cache.invalidate();
self.switch_source_cache.invalidate();
self.is_cyclic.invalidate();
(&mut self.basic_blocks, &mut self.local_decls, &mut self.var_debug_info)
}
Expand Down Expand Up @@ -541,6 +549,11 @@ impl<'tcx> Body<'tcx> {
self.predecessor_cache.compute(&self.basic_blocks)
}

#[inline]
pub fn switch_sources(&self) -> &SwitchSources {
self.switch_source_cache.compute(&self.basic_blocks)
}

#[inline]
pub fn dominators(&self) -> Dominators<BasicBlock> {
dominators(self)
Expand Down
82 changes: 82 additions & 0 deletions compiler/rustc_middle/src/mir/switch_sources.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//! Lazily compute the inverse of each `SwitchInt`'s switch targets. Modeled after
//! `Predecessors`/`PredecessorCache`.

use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::OnceCell;
use rustc_index::vec::IndexVec;
use rustc_serialize as serialize;
use smallvec::SmallVec;

use crate::mir::{BasicBlock, BasicBlockData, Terminator, TerminatorKind};

pub type SwitchSources = IndexVec<BasicBlock, IndexVec<BasicBlock, SmallVec<[Option<u128>; 1]>>>;

#[derive(Clone, Debug)]
pub(super) struct SwitchSourceCache {
cache: OnceCell<SwitchSources>,
}

impl SwitchSourceCache {
#[inline]
pub(super) fn new() -> Self {
SwitchSourceCache { cache: OnceCell::new() }
}

/// Invalidates the switch source cache.
#[inline]
pub(super) fn invalidate(&mut self) {
self.cache = OnceCell::new();
}

/// Returns the switch sources for this MIR.
#[inline]
pub(super) fn compute(
&self,
basic_blocks: &IndexVec<BasicBlock, BasicBlockData<'_>>,
) -> &SwitchSources {
self.cache.get_or_init(|| {
let mut switch_sources = IndexVec::from_elem(
IndexVec::from_elem(SmallVec::new(), basic_blocks),
basic_blocks,
);
for (bb, data) in basic_blocks.iter_enumerated() {
if let Some(Terminator {
kind: TerminatorKind::SwitchInt { targets, .. }, ..
}) = &data.terminator
{
for (value, target) in targets.iter() {
switch_sources[target][bb].push(Some(value));
}
switch_sources[targets.otherwise()][bb].push(None);
}
}

switch_sources
})
}
}

impl<S: serialize::Encoder> serialize::Encodable<S> for SwitchSourceCache {
#[inline]
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_unit()
}
}

impl<D: serialize::Decoder> serialize::Decodable<D> for SwitchSourceCache {
#[inline]
fn decode(_: &mut D) -> Self {
Self::new()
}
}

impl<CTX> HashStable<CTX> for SwitchSourceCache {
#[inline]
fn hash_stable(&self, _: &mut CTX, _: &mut StableHasher) {
// do nothing
}
}

TrivialTypeFoldableAndLiftImpls! {
SwitchSourceCache,
}
62 changes: 57 additions & 5 deletions compiler/rustc_mir_dataflow/src/framework/direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ impl Direction for Backward {
);
propagate(pred, &tmp);
}

mir::TerminatorKind::InlineAsm {
destination: Some(dest), ref operands, ..
} if dest == bb => {
Expand All @@ -266,6 +267,23 @@ impl Direction for Backward {
propagate(pred, &tmp);
}

mir::TerminatorKind::SwitchInt { targets: _, ref discr, switch_ty: _ } => {
let mut applier = BackwardSwitchIntEdgeEffectsApplier {
pred,
exit_state,
values: &body.switch_sources()[bb][pred],
bb,
propagate: &mut propagate,
effects_applied: false,
};

analysis.apply_switch_int_edge_effects(pred, discr, &mut applier);

if !applier.effects_applied {
propagate(pred, exit_state)
}
}

// Ignore dead unwinds.
mir::TerminatorKind::Call { cleanup: Some(unwind), .. }
| mir::TerminatorKind::Assert { cleanup: Some(unwind), .. }
Expand All @@ -286,6 +304,37 @@ impl Direction for Backward {
}
}

struct BackwardSwitchIntEdgeEffectsApplier<'a, D, F> {
pred: BasicBlock,
exit_state: &'a mut D,
values: &'a [Option<u128>],
bb: BasicBlock,
propagate: &'a mut F,

effects_applied: bool,
}

impl<D, F> super::SwitchIntEdgeEffects<D> for BackwardSwitchIntEdgeEffectsApplier<'_, D, F>
where
D: Clone,
F: FnMut(BasicBlock, &D),
{
fn apply(&mut self, mut apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget)) {
assert!(!self.effects_applied);

let targets = self.values.iter().map(|&value| SwitchIntTarget { value, target: self.bb });

let mut tmp = None;
for target in targets {
let tmp = opt_clone_from_or_clone(&mut tmp, self.exit_state);
apply_edge_effect(tmp, target);
(self.propagate)(self.pred, tmp);
}

self.effects_applied = true;
}
}

/// Dataflow that runs from the entry of a block (the first statement), to its exit (terminator).
pub struct Forward;

Expand Down Expand Up @@ -528,7 +577,7 @@ impl Direction for Forward {
}

SwitchInt { ref targets, ref discr, switch_ty: _ } => {
let mut applier = SwitchIntEdgeEffectApplier {
let mut applier = ForwardSwitchIntEdgeEffectsApplier {
exit_state,
targets,
propagate,
Expand All @@ -537,8 +586,11 @@ impl Direction for Forward {

analysis.apply_switch_int_edge_effects(bb, discr, &mut applier);

let SwitchIntEdgeEffectApplier {
exit_state, mut propagate, effects_applied, ..
let ForwardSwitchIntEdgeEffectsApplier {
exit_state,
mut propagate,
effects_applied,
..
} = applier;

if !effects_applied {
Expand All @@ -551,15 +603,15 @@ impl Direction for Forward {
}
}

struct SwitchIntEdgeEffectApplier<'a, D, F> {
struct ForwardSwitchIntEdgeEffectsApplier<'a, D, F> {
exit_state: &'a mut D,
targets: &'a SwitchTargets,
propagate: F,

effects_applied: bool,
}

impl<D, F> super::SwitchIntEdgeEffects<D> for SwitchIntEdgeEffectApplier<'_, D, F>
impl<D, F> super::SwitchIntEdgeEffects<D> for ForwardSwitchIntEdgeEffectsApplier<'_, D, F>
where
D: Clone,
F: FnMut(BasicBlock, &D),
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_mir_dataflow/src/framework/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,6 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
/// about a given `SwitchInt` terminator for each one of its edges—and more efficient—the
/// engine doesn't need to clone the exit state for a block unless
/// `SwitchIntEdgeEffects::apply` is actually called.
///
/// FIXME: This class of effects is not supported for backward dataflow analyses.
fn apply_switch_int_edge_effects(
&self,
_block: BasicBlock,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_dataflow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub use self::drop_flag_effects::{
pub use self::framework::{
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, Backward, CallReturnPlaces,
Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice, Results, ResultsCursor,
ResultsRefCursor, ResultsVisitable, ResultsVisitor,
ResultsRefCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
};

use self::move_paths::MoveData;
Expand Down
Loading

0 comments on commit 6252304

Please sign in to comment.