Skip to content
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

Rollup of 5 pull requests #97849

Merged
merged 10 commits into from
Jun 8, 2022
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_middle::ty::layout::{
use rustc_middle::ty::{
self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable,
};
use rustc_mir_dataflow::storage::AlwaysLiveLocals;
use rustc_mir_dataflow::storage::always_live_locals;
use rustc_query_system::ich::StableHashingContext;
use rustc_session::Limit;
use rustc_span::{Pos, Span};
Expand Down Expand Up @@ -715,7 +715,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

// Now mark those locals as dead that we do not want to initialize
// Mark locals that use `Storage*` annotations as dead on function entry.
let always_live = AlwaysLiveLocals::new(self.body());
let always_live = always_live_locals(self.body());
for local in locals.indices() {
if !always_live.contains(local) {
locals[local].value = LocalValue::Dead;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::mir::{
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable};
use rustc_mir_dataflow::impls::MaybeStorageLive;
use rustc_mir_dataflow::storage::AlwaysLiveLocals;
use rustc_mir_dataflow::storage::always_live_locals;
use rustc_mir_dataflow::{Analysis, ResultsCursor};
use rustc_target::abi::{Size, VariantIdx};

Expand Down Expand Up @@ -48,7 +48,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
let param_env = tcx.param_env(def_id);
let mir_phase = self.mir_phase;

let always_live_locals = AlwaysLiveLocals::new(body);
let always_live_locals = always_live_locals(body);
let storage_liveness = MaybeStorageLive::new(always_live_locals)
.into_engine(tcx, body)
.iterate_to_fixpoint()
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1542,11 +1542,19 @@ extern "C" bool LLVMRustConstInt128Get(LLVMValueRef CV, bool sext, uint64_t *hig
auto C = unwrap<llvm::ConstantInt>(CV);
if (C->getBitWidth() > 128) { return false; }
APInt AP;
#if LLVM_VERSION_GE(15, 0)
if (sext) {
AP = C->getValue().sext(128);
} else {
AP = C->getValue().zext(128);
}
#else
if (sext) {
AP = C->getValue().sextOrSelf(128);
} else {
AP = C->getValue().zextOrSelf(128);
}
#endif
*low = AP.getLoBits(64).getZExtValue();
*high = AP.getHiBits(64).getZExtValue();
return true;
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir_dataflow/src/framework/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ where
/// For backward analyses, this is the state that will be propagated to its
/// predecessors (ignoring edge-specific effects).
pub fn seek_to_block_start(&mut self, block: BasicBlock) {
if A::Direction::is_forward() {
if A::Direction::IS_FORWARD {
self.seek_to_block_entry(block)
} else {
self.seek_after(Location { block, statement_index: 0 }, Effect::Primary)
Expand All @@ -123,7 +123,7 @@ where
/// For forward analyses, this is the state that will be propagated to its
/// successors (ignoring edge-specific effects).
pub fn seek_to_block_end(&mut self, block: BasicBlock) {
if A::Direction::is_backward() {
if A::Direction::IS_BACKWARD {
self.seek_to_block_entry(block)
} else {
self.seek_after(self.body.terminator_loc(block), Effect::Primary)
Expand Down Expand Up @@ -157,7 +157,7 @@ where
self.seek_to_block_entry(target.block);
} else if let Some(curr_effect) = self.pos.curr_effect_index {
let mut ord = curr_effect.statement_index.cmp(&target.statement_index);
if A::Direction::is_backward() {
if A::Direction::IS_BACKWARD {
ord = ord.reverse()
}

Expand All @@ -173,7 +173,7 @@ where
debug_assert_eq!(target.block, self.pos.block);

let block_data = &self.body[target.block];
let next_effect = if A::Direction::is_forward() {
let next_effect = if A::Direction::IS_FORWARD {
#[rustfmt::skip]
self.pos.curr_effect_index.map_or_else(
|| Effect::Before.at_index(0),
Expand Down
14 changes: 4 additions & 10 deletions compiler/rustc_mir_dataflow/src/framework/direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ use super::{
};

pub trait Direction {
fn is_forward() -> bool;
const IS_FORWARD: bool;

fn is_backward() -> bool {
!Self::is_forward()
}
const IS_BACKWARD: bool = !Self::IS_FORWARD;

/// Applies all effects between the given `EffectIndex`s.
///
Expand Down Expand Up @@ -68,9 +66,7 @@ pub trait Direction {
pub struct Backward;

impl Direction for Backward {
fn is_forward() -> bool {
false
}
const IS_FORWARD: bool = false;

fn apply_effects_in_block<'tcx, A>(
analysis: &A,
Expand Down Expand Up @@ -338,9 +334,7 @@ where
pub struct Forward;

impl Direction for Forward {
fn is_forward() -> bool {
true
}
const IS_FORWARD: bool = true;

fn apply_effects_in_block<'tcx, A>(
analysis: &A,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_dataflow/src/framework/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ where
let mut entry_sets = IndexVec::from_elem(bottom_value.clone(), body.basic_blocks());
analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);

if A::Direction::is_backward() && entry_sets[mir::START_BLOCK] != bottom_value {
if A::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != bottom_value {
bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
}

Expand Down Expand Up @@ -200,7 +200,7 @@ where
let mut dirty_queue: WorkQueue<BasicBlock> =
WorkQueue::with_none(body.basic_blocks().len());

if A::Direction::is_forward() {
if A::Direction::IS_FORWARD {
for (bb, _) in traversal::reverse_postorder(body) {
dirty_queue.insert(bb);
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir_dataflow/src/framework/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ where
// Write the full dataflow state immediately after the terminator if it differs from the
// state at block entry.
self.results.seek_to_block_end(block);
if self.results.get() != &block_start_state || A::Direction::is_backward() {
if self.results.get() != &block_start_state || A::Direction::IS_BACKWARD {
let after_terminator_name = match terminator.kind {
mir::TerminatorKind::Call { target: Some(_), .. } => "(on unwind)",
_ => "(on end)",
Expand Down Expand Up @@ -390,7 +390,7 @@ where
let mut afters = diffs.after.into_iter();

let next_in_dataflow_order = |it: &mut std::vec::IntoIter<_>| {
if A::Direction::is_forward() { it.next().unwrap() } else { it.next_back().unwrap() }
if A::Direction::IS_FORWARD { it.next().unwrap() } else { it.next_back().unwrap() }
};

for (i, statement) in body[block].statements.iter().enumerate() {
Expand Down Expand Up @@ -527,7 +527,7 @@ where
_block_data: &mir::BasicBlockData<'tcx>,
_block: BasicBlock,
) {
if A::Direction::is_forward() {
if A::Direction::IS_FORWARD {
self.prev_state.clone_from(state);
}
}
Expand All @@ -538,7 +538,7 @@ where
_block_data: &mir::BasicBlockData<'tcx>,
_block: BasicBlock,
) {
if A::Direction::is_backward() {
if A::Direction::IS_BACKWARD {
self.prev_state.clone_from(state);
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_dataflow/src/framework/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
SeekTarget::After(loc) => Effect::Primary.at_index(loc.statement_index),
};

let mut pos = if D::is_forward() {
let mut pos = if D::IS_FORWARD {
Effect::Before.at_index(0)
} else {
Effect::Before.at_index(self.body[block].statements.len())
Expand All @@ -153,7 +153,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
return ret;
}

if D::is_forward() {
if D::IS_FORWARD {
pos = pos.next_in_forward_order();
} else {
pos = pos.next_in_backward_order();
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
pub use super::*;

use crate::storage::AlwaysLiveLocals;
use crate::{CallReturnPlaces, GenKill, Results, ResultsRefCursor};
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::*;
use std::cell::RefCell;

#[derive(Clone)]
pub struct MaybeStorageLive {
always_live_locals: AlwaysLiveLocals,
always_live_locals: BitSet<Local>,
}

impl MaybeStorageLive {
pub fn new(always_live_locals: AlwaysLiveLocals) -> Self {
pub fn new(always_live_locals: BitSet<Local>) -> Self {
MaybeStorageLive { always_live_locals }
}
}
Expand Down
34 changes: 8 additions & 26 deletions compiler/rustc_mir_dataflow/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,17 @@ use rustc_middle::mir::{self, Local};
//
// FIXME: Currently, we need to traverse the entire MIR to compute this. We should instead store it
// as a field in the `LocalDecl` for each `Local`.
#[derive(Debug, Clone)]
pub struct AlwaysLiveLocals(BitSet<Local>);
pub fn always_live_locals(body: &mir::Body<'_>) -> BitSet<Local> {
let mut always_live_locals = BitSet::new_filled(body.local_decls.len());

impl AlwaysLiveLocals {
pub fn new(body: &mir::Body<'_>) -> Self {
let mut always_live_locals = AlwaysLiveLocals(BitSet::new_filled(body.local_decls.len()));

for block in body.basic_blocks() {
for statement in &block.statements {
use mir::StatementKind::{StorageDead, StorageLive};
if let StorageLive(l) | StorageDead(l) = statement.kind {
always_live_locals.0.remove(l);
}
for block in body.basic_blocks() {
for statement in &block.statements {
use mir::StatementKind::{StorageDead, StorageLive};
if let StorageLive(l) | StorageDead(l) = statement.kind {
always_live_locals.remove(l);
}
}

always_live_locals
}

pub fn into_inner(self) -> BitSet<Local> {
self.0
}
}

impl std::ops::Deref for AlwaysLiveLocals {
type Target = BitSet<Local>;

#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
always_live_locals
}
10 changes: 5 additions & 5 deletions compiler/rustc_mir_transform/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ struct TransformVisitor<'tcx> {
suspension_points: Vec<SuspensionPoint<'tcx>>,

// The set of locals that have no `StorageLive`/`StorageDead` annotations.
always_live_locals: storage::AlwaysLiveLocals,
always_live_locals: BitSet<Local>,

// The original RETURN_PLACE local
new_ret_local: Local,
Expand Down Expand Up @@ -450,7 +450,7 @@ struct LivenessInfo {
fn locals_live_across_suspend_points<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
always_live_locals: &storage::AlwaysLiveLocals,
always_live_locals: &BitSet<Local>,
movable: bool,
) -> LivenessInfo {
let body_ref: &Body<'_> = &body;
Expand Down Expand Up @@ -615,7 +615,7 @@ impl ops::Deref for GeneratorSavedLocals {
fn compute_storage_conflicts<'mir, 'tcx>(
body: &'mir Body<'tcx>,
saved_locals: &GeneratorSavedLocals,
always_live_locals: storage::AlwaysLiveLocals,
always_live_locals: BitSet<Local>,
requires_storage: rustc_mir_dataflow::Results<'tcx, MaybeRequiresStorage<'mir, 'tcx>>,
) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> {
assert_eq!(body.local_decls.len(), saved_locals.domain_size());
Expand All @@ -625,7 +625,7 @@ fn compute_storage_conflicts<'mir, 'tcx>(

// Locals that are always live or ones that need to be stored across
// suspension points are not eligible for overlap.
let mut ineligible_locals = always_live_locals.into_inner();
let mut ineligible_locals = always_live_locals;
ineligible_locals.intersect(&**saved_locals);

// Compute the storage conflicts for all eligible locals.
Expand Down Expand Up @@ -1300,7 +1300,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
},
);

let always_live_locals = storage::AlwaysLiveLocals::new(&body);
let always_live_locals = storage::always_live_locals(&body);

let liveness_info =
locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
Expand Down
19 changes: 9 additions & 10 deletions compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1577,18 +1577,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
name: Symbol,
) -> ErrorGuaranteed {
let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
if let (true, Ok(snippet)) = (
self.tcx()
.resolutions(())
.confused_type_with_std_module
.keys()
.any(|full_span| full_span.contains(span)),
self.tcx().sess.source_map().span_to_snippet(span),
) {
if self
.tcx()
.resolutions(())
.confused_type_with_std_module
.keys()
.any(|full_span| full_span.contains(span))
{
err.span_suggestion(
span,
span.shrink_to_lo(),
"you are looking for the module in `std`, not the primitive type",
format!("std::{}", snippet),
"std::".to_string(),
Applicability::MachineApplicable,
);
} else {
Expand Down
24 changes: 10 additions & 14 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,26 +327,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}
if let Some(span) = tcx.resolutions(()).confused_type_with_std_module.get(&span) {
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*span) {
err.span_suggestion(
*span,
"you are looking for the module in `std`, \
not the primitive type",
format!("std::{}", snippet),
Applicability::MachineApplicable,
);
}
err.span_suggestion(
span.shrink_to_lo(),
"you are looking for the module in `std`, not the primitive type",
"std::".to_string(),
Applicability::MachineApplicable,
);
}
if let ty::RawPtr(_) = &actual.kind() {
err.note(
"try using `<*const T>::as_ref()` to get a reference to the \
type behind the pointer: https://doc.rust-lang.org/std/\
primitive.pointer.html#method.as_ref",
type behind the pointer: https://doc.rust-lang.org/std/\
primitive.pointer.html#method.as_ref",
);
err.note(
"using `<*const T>::as_ref()` on a pointer \
which is unaligned or points to invalid \
or uninitialized memory is undefined behavior",
"using `<*const T>::as_ref()` on a pointer which is unaligned or points \
to invalid or uninitialized memory is undefined behavior",
);
}

Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/async-await/issues/issue-95307.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// edition:2018

// Regression test for #95307.
// The ICE occurred on all the editions, specifying edition:2018 to reduce diagnostics.

pub trait C {
async fn new() -> [u8; _];
//~^ ERROR: functions in traits cannot be declared `async`
//~| ERROR: using `_` for array lengths is unstable
//~| ERROR: in expressions, `_` can only be used on the left-hand side of an assignment
}

fn main() {}
Loading