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 8 pull requests #101017

Merged
merged 21 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
54d35e7
distinguish the method and associated function diagnostic information
Jul 8, 2022
97c963d
make slice::{split_at,split_at_unchecked} const functions
tspiteri Aug 2, 2022
83f081f
Remove unstable Result::into_ok_or_err
dtolnay Aug 15, 2022
39809c5
Replace a try_fold in rustc_transmute to use ControlFlow instead of R…
dtolnay Aug 15, 2022
289d7cc
Reduce code size of `assert_matches_failed`
a1phyr Aug 23, 2022
b997af9
Handle `Err` in `ast::LitKind::to_token_lit`.
nnethercote Aug 24, 2022
31d892a
Fix liveness analysis for yield terminators
tmiasko Aug 1, 2022
4462b4a
Elaborate all box dereferences in `ElaborateBoxDerefs`
tmiasko Aug 1, 2022
58eabb2
Add method that applies DefUse effect
tmiasko Aug 25, 2022
4394ea8
Inline trivial `From<Local> for Place<'_>` impl
tmiasko Aug 25, 2022
bc3d719
review
tspiteri Aug 25, 2022
45cc8cb
rustdoc: remove unused CSS for `.multi-column`
notriddle Aug 25, 2022
258d367
Adding support for rustc_serialize encode and decode for Box and Vec …
Aug 25, 2022
f7f80c2
Rollup merge of #99064 - lyming2007:issue-97687-fix, r=estebank
JohnTitor Aug 26, 2022
28457e1
Rollup merge of #99920 - emarteca:custom-allocator-support, r=oli-obk
JohnTitor Aug 26, 2022
55562c7
Rollup merge of #100034 - tmiasko:elaborate-box-derefs, r=oli-obk
JohnTitor Aug 26, 2022
e193f46
Rollup merge of #100076 - tspiteri:const_slice_split_at, r=oli-obk
JohnTitor Aug 26, 2022
ba31a9b
Rollup merge of #100604 - dtolnay:okorerr, r=m-ou-se
JohnTitor Aug 26, 2022
6849555
Rollup merge of #100933 - a1phyr:cheap_assert_match_failed, r=JoshTri…
JohnTitor Aug 26, 2022
d4a5ec1
Rollup merge of #100978 - nnethercote:fix-100948, r=petrochenkov
JohnTitor Aug 26, 2022
b4d5f48
Rollup merge of #101010 - notriddle:notriddle/multi-column, r=jsha
JohnTitor Aug 26, 2022
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
4 changes: 3 additions & 1 deletion compiler/rustc_ast/src/util/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ impl LitKind {
let symbol = if value { kw::True } else { kw::False };
(token::Bool, symbol, None)
}
LitKind::Err => unreachable!(),
// This only shows up in places like `-Zunpretty=hir` output, so we
// don't bother to produce something useful.
LitKind::Err => (token::Err, Symbol::intern("<bad-literal>"), None),
};

token::Lit::new(kind, symbol, suffix)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ index 06c7be0..359e2e7 100644
@@ -75,7 +75,6 @@
#![feature(never_type)]
#![feature(unwrap_infallible)]
#![feature(result_into_ok_or_err)]
-#![feature(portable_simd)]
#![feature(ptr_metadata)]
#![feature(once_cell)]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1531,6 +1531,7 @@ impl<'tcx> Place<'tcx> {
}

impl From<Local> for Place<'_> {
#[inline]
fn from(local: Local) -> Self {
Place { local, projection: List::empty() }
}
Expand Down
105 changes: 65 additions & 40 deletions compiler/rustc_mir_dataflow/src/impls/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ use crate::{Analysis, AnalysisDomain, Backward, CallReturnPlaces, GenKill, GenKi
/// [liveness]: https://en.wikipedia.org/wiki/Live_variable_analysis
pub struct MaybeLiveLocals;

impl MaybeLiveLocals {
fn transfer_function<'a, T>(&self, trans: &'a mut T) -> TransferFunction<'a, T> {
TransferFunction(trans)
}
}

impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals {
type Domain = ChunkedBitSet<Local>;
type Direction = Backward;
Expand All @@ -54,7 +48,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
statement: &mir::Statement<'tcx>,
location: Location,
) {
self.transfer_function(trans).visit_statement(statement, location);
TransferFunction(trans).visit_statement(statement, location);
}

fn terminator_effect(
Expand All @@ -63,7 +57,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
terminator: &mir::Terminator<'tcx>,
location: Location,
) {
self.transfer_function(trans).visit_terminator(terminator, location);
TransferFunction(trans).visit_terminator(terminator, location);
}

fn call_return_effect(
Expand All @@ -85,9 +79,11 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
_resume_block: mir::BasicBlock,
resume_place: mir::Place<'tcx>,
) {
if let Some(local) = resume_place.as_local() {
trans.kill(local);
}
YieldResumeEffect(trans).visit_place(
&resume_place,
PlaceContext::MutatingUse(MutatingUseContext::Yield),
Location::START,
)
}
}

Expand All @@ -98,28 +94,51 @@ where
T: GenKill<Local>,
{
fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) {
let local = place.local;

// We purposefully do not call `super_place` here to avoid calling `visit_local` for this
// place with one of the `Projection` variants of `PlaceContext`.
self.visit_projection(place.as_ref(), context, location);
if let PlaceContext::MutatingUse(MutatingUseContext::Yield) = context {
// The resume place is evaluated and assigned to only after generator resumes, so its
// effect is handled separately in `yield_resume_effect`.
return;
}

match DefUse::for_place(*place, context) {
Some(DefUse::Def) => self.0.kill(local),
Some(DefUse::Use) => self.0.gen(local),
Some(DefUse::Def) => {
if let PlaceContext::MutatingUse(
MutatingUseContext::Call | MutatingUseContext::AsmOutput,
) = context
{
// For the associated terminators, this is only a `Def` when the terminator returns
// "successfully." As such, we handle this case separately in `call_return_effect`
// above. However, if the place looks like `*_5`, this is still unconditionally a use of
// `_5`.
} else {
self.0.kill(place.local);
}
}
Some(DefUse::Use) => self.0.gen(place.local),
None => {}
}

self.visit_projection(place.as_ref(), context, location);
}

fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
// Because we do not call `super_place` above, `visit_local` is only called for locals that
// do not appear as part of a `Place` in the MIR. This handles cases like the implicit use
// of the return place in a `Return` terminator or the index in an `Index` projection.
match DefUse::for_place(local.into(), context) {
Some(DefUse::Def) => self.0.kill(local),
Some(DefUse::Use) => self.0.gen(local),
None => {}
}
DefUse::apply(self.0, local.into(), context);
}
}

struct YieldResumeEffect<'a, T>(&'a mut T);

impl<'tcx, T> Visitor<'tcx> for YieldResumeEffect<'_, T>
where
T: GenKill<Local>,
{
fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) {
DefUse::apply(self.0, *place, context);
self.visit_projection(place.as_ref(), context, location);
}

fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
DefUse::apply(self.0, local.into(), context);
}
}

Expand All @@ -130,11 +149,25 @@ enum DefUse {
}

impl DefUse {
fn apply<'tcx>(trans: &mut impl GenKill<Local>, place: Place<'tcx>, context: PlaceContext) {
match DefUse::for_place(place, context) {
Some(DefUse::Def) => trans.kill(place.local),
Some(DefUse::Use) => trans.gen(place.local),
None => {}
}
}

fn for_place<'tcx>(place: Place<'tcx>, context: PlaceContext) -> Option<DefUse> {
match context {
PlaceContext::NonUse(_) => None,

PlaceContext::MutatingUse(MutatingUseContext::Store | MutatingUseContext::Deinit) => {
PlaceContext::MutatingUse(
MutatingUseContext::Call
| MutatingUseContext::Yield
| MutatingUseContext::AsmOutput
| MutatingUseContext::Store
| MutatingUseContext::Deinit,
) => {
if place.is_indirect() {
// Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a
// use.
Expand All @@ -152,16 +185,6 @@ impl DefUse {
place.is_indirect().then_some(DefUse::Use)
}

// For the associated terminators, this is only a `Def` when the terminator returns
// "successfully." As such, we handle this case separately in `call_return_effect`
// above. However, if the place looks like `*_5`, this is still unconditionally a use of
// `_5`.
PlaceContext::MutatingUse(
MutatingUseContext::Call
| MutatingUseContext::Yield
| MutatingUseContext::AsmOutput,
) => place.is_indirect().then_some(DefUse::Use),

// All other contexts are uses...
PlaceContext::MutatingUse(
MutatingUseContext::AddressOf
Expand Down Expand Up @@ -290,8 +313,10 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
_resume_block: mir::BasicBlock,
resume_place: mir::Place<'tcx>,
) {
if let Some(local) = resume_place.as_local() {
trans.remove(local);
}
YieldResumeEffect(trans).visit_place(
&resume_place,
PlaceContext::MutatingUse(MutatingUseContext::Yield),
Location::START,
)
}
}
23 changes: 2 additions & 21 deletions compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,27 +107,8 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
let mut visitor =
ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch };

for (block, BasicBlockData { statements, terminator, .. }) in
body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut()
{
let mut index = 0;
for statement in statements {
let location = Location { block, statement_index: index };
visitor.visit_statement(statement, location);
index += 1;
}

let location = Location { block, statement_index: index };
match terminator {
// yielding into a box is handled when lowering generators
Some(Terminator { kind: TerminatorKind::Yield { value, .. }, .. }) => {
visitor.visit_operand(value, location);
}
Some(terminator) => {
visitor.visit_terminator(terminator, location);
}
None => {}
}
for (block, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
visitor.visit_basic_block_data(block, data);
}

visitor.patch.apply(body);
Expand Down
88 changes: 7 additions & 81 deletions compiler/rustc_mir_transform/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1182,8 +1182,6 @@ fn create_cases<'tcx>(
transform: &TransformVisitor<'tcx>,
operation: Operation,
) -> Vec<(usize, BasicBlock)> {
let tcx = transform.tcx;

let source_info = SourceInfo::outermost(body.span);

transform
Expand Down Expand Up @@ -1216,85 +1214,13 @@ fn create_cases<'tcx>(
if operation == Operation::Resume {
// Move the resume argument to the destination place of the `Yield` terminator
let resume_arg = Local::new(2); // 0 = return, 1 = self

// handle `box yield` properly
let box_place = if let [projection @ .., ProjectionElem::Deref] =
&**point.resume_arg.projection
{
let box_place =
Place::from(point.resume_arg.local).project_deeper(projection, tcx);

let box_ty = box_place.ty(&body.local_decls, tcx).ty;

if box_ty.is_box() { Some((box_place, box_ty)) } else { None }
} else {
None
};

if let Some((box_place, box_ty)) = box_place {
let unique_did = box_ty
.ty_adt_def()
.expect("expected Box to be an Adt")
.non_enum_variant()
.fields[0]
.did;

let Some(nonnull_def) = tcx.type_of(unique_did).ty_adt_def() else {
span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
};

let nonnull_did = nonnull_def.non_enum_variant().fields[0].did;

let (unique_ty, nonnull_ty, ptr_ty) =
crate::elaborate_box_derefs::build_ptr_tys(
tcx,
box_ty.boxed_ty(),
unique_did,
nonnull_did,
);

let ptr_local = body.local_decls.push(LocalDecl::new(ptr_ty, body.span));

statements.push(Statement {
source_info,
kind: StatementKind::StorageLive(ptr_local),
});

statements.push(Statement {
source_info,
kind: StatementKind::Assign(Box::new((
Place::from(ptr_local),
Rvalue::Use(Operand::Copy(box_place.project_deeper(
&crate::elaborate_box_derefs::build_projection(
unique_ty, nonnull_ty, ptr_ty,
),
tcx,
))),
))),
});

statements.push(Statement {
source_info,
kind: StatementKind::Assign(Box::new((
Place::from(ptr_local)
.project_deeper(&[ProjectionElem::Deref], tcx),
Rvalue::Use(Operand::Move(resume_arg.into())),
))),
});

statements.push(Statement {
source_info,
kind: StatementKind::StorageDead(ptr_local),
});
} else {
statements.push(Statement {
source_info,
kind: StatementKind::Assign(Box::new((
point.resume_arg,
Rvalue::Use(Operand::Move(resume_arg.into())),
))),
});
}
statements.push(Statement {
source_info,
kind: StatementKind::Assign(Box::new((
point.resume_arg,
Rvalue::Use(Operand::Move(resume_arg.into())),
))),
});
}

// Then jump to the real target
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_serialize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Core encoding and decoding interfaces.
#![feature(maybe_uninit_slice)]
#![feature(let_else)]
#![feature(new_uninit)]
#![feature(allocator_api)]
#![cfg_attr(test, feature(test))]
#![allow(rustc::internal)]
#![deny(rustc::untranslatable_diagnostic)]
Expand Down
26 changes: 15 additions & 11 deletions compiler/rustc_serialize/src/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Core encoding and decoding interfaces.
*/

use std::alloc::Allocator;
use std::borrow::Cow;
use std::cell::{Cell, RefCell};
use std::marker::PhantomData;
Expand Down Expand Up @@ -229,9 +230,9 @@ impl<D: Decoder, T> Decodable<D> for PhantomData<T> {
}
}

impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<[T]> {
fn decode(d: &mut D) -> Box<[T]> {
let v: Vec<T> = Decodable::decode(d);
impl<D: Decoder, A: Allocator + Default, T: Decodable<D>> Decodable<D> for Box<[T], A> {
fn decode(d: &mut D) -> Box<[T], A> {
let v: Vec<T, A> = Decodable::decode(d);
v.into_boxed_slice()
}
}
Expand Down Expand Up @@ -264,12 +265,13 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> {
}
}

impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
default fn decode(d: &mut D) -> Vec<T> {
impl<D: Decoder, T: Decodable<D>, A: Allocator + Default> Decodable<D> for Vec<T, A> {
default fn decode(d: &mut D) -> Vec<T, A> {
let len = d.read_usize();
let allocator = A::default();
// SAFETY: we set the capacity in advance, only write elements, and
// only set the length at the end once the writing has succeeded.
let mut vec = Vec::with_capacity(len);
let mut vec = Vec::with_capacity_in(len, allocator);
unsafe {
let ptr: *mut T = vec.as_mut_ptr();
for i in 0..len {
Expand Down Expand Up @@ -457,13 +459,15 @@ impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<T> {
}
}

impl<S: Encoder, T: ?Sized + Encodable<S>> Encodable<S> for Box<T> {
impl<S: Encoder, T: ?Sized + Encodable<S>, A: Allocator + Default> Encodable<S> for Box<T, A> {
fn encode(&self, s: &mut S) {
(**self).encode(s);
(**self).encode(s)
}
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<T> {
fn decode(d: &mut D) -> Box<T> {
Box::new(Decodable::decode(d))

impl<D: Decoder, A: Allocator + Default, T: Decodable<D>> Decodable<D> for Box<T, A> {
fn decode(d: &mut D) -> Box<T, A> {
let allocator = A::default();
Box::new_in(Decodable::decode(d), allocator)
}
}
Loading