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 10 pull requests #80496

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6e852cc
remove redundant clones (clippy::redundant_clone)
matthiaskrgr Dec 24, 2020
a8775d4
Edit rustc_span documentation
pierwill Dec 24, 2020
1b77f8e
Constify intrinsics::copy[_nonoverlapping]
usbalbin Dec 26, 2020
7594d2a
Constify ptr::read and ptr::read_unaligned
usbalbin Dec 26, 2020
d4fd798
Constify *const T::read[_unaligned] and *mut T::read[_unaligned]
usbalbin Dec 26, 2020
1975a6e
Constify MaybeUninit::assume_init_read
usbalbin Dec 26, 2020
5e27765
Add tests
usbalbin Dec 26, 2020
0cea1c9
Added reference to tracking issue #80377
usbalbin Dec 26, 2020
0f25712
Revert "Cleanup markdown span handling"
Dec 26, 2020
7ac02bd
Don't give an error when creating a file for the first time
jyn514 Dec 27, 2020
c482ffd
bump rust-installer submodule
pietroalbini Dec 14, 2020
2f58422
Improvements to NatVis support
Dec 22, 2020
122e91c
promotion: factor some common code into validate_ref
RalfJung Dec 28, 2020
c177e68
merge two match'es for more exhaustiveness
RalfJung Dec 28, 2020
8d5dc8c
Add missing commas to `rustc_ast_pretty::pp` docs
camelid Dec 28, 2020
4a90a58
make more matches exhaustive
RalfJung Dec 28, 2020
0a2034d
bootstrap: add the dist.compression-formats option
pietroalbini Dec 14, 2020
d0d0ee0
ci: stop producing gzip-compressed dist tarballs
pietroalbini Dec 28, 2020
51cec58
fix a comment
RalfJung Dec 29, 2020
c857cbe
Lint on redundant trailing semicolon after item
Aaron1011 Dec 7, 2020
21ed141
Remove trailing semicolon in librustdoc
Aaron1011 Dec 8, 2020
4c4700d
Remove unnecessary semicolon from Rustdoc-generated code
Aaron1011 Dec 28, 2020
6bef37c
Remove unnecessary semicolon from Clippy test
Aaron1011 Dec 29, 2020
927a94a
Rollup merge of #79684 - usbalbin:const_copy, r=oli-obk
Dylan-DPC Dec 30, 2020
b6e565f
Rollup merge of #79812 - Aaron1011:lint-item-trailing-semi, r=oli-obk
Dylan-DPC Dec 30, 2020
7a32e57
Rollup merge of #80311 - sivadeilra:natvis, r=petrochenkov
Dylan-DPC Dec 30, 2020
2932e87
Rollup merge of #80348 - matthiaskrgr:less_clones, r=Dylan-DPC
Dylan-DPC Dec 30, 2020
16550d2
Rollup merge of #80358 - pierwill:edit_rustc_span, r=lcnr
Dylan-DPC Dec 30, 2020
9b5cdd8
Rollup merge of #80381 - rust-lang:revert-80244-spans, r=GuillaumeGomez
Dylan-DPC Dec 30, 2020
b432edb
Rollup merge of #80424 - jyn514:bootstrap-cleanup, r=Mark-Simulacrum
Dylan-DPC Dec 30, 2020
13ef40a
Rollup merge of #80435 - pietroalbini:compression-formats, r=Mark-Sim…
Dylan-DPC Dec 30, 2020
fd364d6
Rollup merge of #80457 - camelid:pretty-docs-commas, r=jonas-schievink
Dylan-DPC Dec 30, 2020
ea43757
Rollup merge of #80458 - RalfJung:promotion-refactor, r=oli-obk
Dylan-DPC Dec 30, 2020
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: 2 additions & 2 deletions compiler/rustc_ast_pretty/src/pp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@
//! breaking inconsistently to become
//!
//! ```
//! foo(hello, there
//! foo(hello, there,
//! good, friends);
//! ```
//!
//! whereas a consistent breaking would yield:
//!
//! ```
//! foo(hello,
//! there
//! there,
//! good,
//! friends);
//! ```
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
T: TypeFoldable<'tcx>,
{
if !value.needs_infer() {
return value.clone(); // Avoid duplicated subst-folding.
return value; // Avoid duplicated subst-folding.
}
let mut r = resolve::OpportunisticVarResolver::new(self);
value.fold_with(&mut r)
Expand Down
20 changes: 3 additions & 17 deletions compiler/rustc_lint/src/redundant_semicolon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,40 +28,26 @@ declare_lint_pass!(RedundantSemicolons => [REDUNDANT_SEMICOLONS]);

impl EarlyLintPass for RedundantSemicolons {
fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) {
let mut after_item_stmt = false;
let mut seq = None;
for stmt in block.stmts.iter() {
match (&stmt.kind, &mut seq) {
(StmtKind::Empty, None) => seq = Some((stmt.span, false)),
(StmtKind::Empty, Some(seq)) => *seq = (seq.0.to(stmt.span), true),
(_, seq) => {
maybe_lint_redundant_semis(cx, seq, after_item_stmt);
after_item_stmt = matches!(stmt.kind, StmtKind::Item(_));
}
(_, seq) => maybe_lint_redundant_semis(cx, seq),
}
}
maybe_lint_redundant_semis(cx, &mut seq, after_item_stmt);
maybe_lint_redundant_semis(cx, &mut seq);
}
}

fn maybe_lint_redundant_semis(
cx: &EarlyContext<'_>,
seq: &mut Option<(Span, bool)>,
after_item_stmt: bool,
) {
fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, bool)>) {
if let Some((span, multiple)) = seq.take() {
// FIXME: Find a better way of ignoring the trailing
// semicolon from macro expansion
if span == rustc_span::DUMMY_SP {
return;
}

// FIXME: Lint on semicolons after item statements
// once doing so doesn't break bootstrapping
if after_item_stmt {
return;
}

cx.struct_span_lint(REDUNDANT_SEMICOLONS, span, |lint| {
let (msg, rem) = if multiple {
("unnecessary trailing semicolons", "remove these semicolons")
Expand Down
23 changes: 23 additions & 0 deletions compiler/rustc_mir/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let result = Scalar::from_uint(truncated_bits, layout.size);
self.write_scalar(result, dest)?;
}
sym::copy | sym::copy_nonoverlapping => {
let elem_ty = instance.substs.type_at(0);
let elem_layout = self.layout_of(elem_ty)?;
let count = self.read_scalar(args[2])?.to_machine_usize(self)?;
let elem_align = elem_layout.align.abi;

let size = elem_layout.size.checked_mul(count, self).ok_or_else(|| {
err_ub_format!("overflow computing total size of `{}`", intrinsic_name)
})?;
let src = self.read_scalar(args[0])?.check_init()?;
let src = self.memory.check_ptr_access(src, size, elem_align)?;
let dest = self.read_scalar(args[1])?.check_init()?;
let dest = self.memory.check_ptr_access(dest, size, elem_align)?;

if let (Some(src), Some(dest)) = (src, dest) {
self.memory.copy(
src,
dest,
size,
intrinsic_name == sym::copy_nonoverlapping,
)?;
}
}
sym::offset => {
let ptr = self.read_scalar(args[0])?.check_init()?;
let offset_count = self.read_scalar(args[1])?.to_machine_isize(self)?;
Expand Down
214 changes: 115 additions & 99 deletions compiler/rustc_mir/src/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub enum TempState {
impl TempState {
pub fn is_promotable(&self) -> bool {
debug!("is_promotable: self={:?}", self);
matches!(self, TempState::Defined { .. } )
matches!(self, TempState::Defined { .. })
}
}

Expand Down Expand Up @@ -309,50 +309,26 @@ impl<'tcx> Validator<'_, 'tcx> {
let statement = &self.body[loc.block].statements[loc.statement_index];
match &statement.kind {
StatementKind::Assign(box (_, Rvalue::Ref(_, kind, place))) => {
match kind {
BorrowKind::Shared | BorrowKind::Mut { .. } => {}

// FIXME(eddyb) these aren't promoted here but *could*
// be promoted as part of a larger value because
// `validate_rvalue` doesn't check them, need to
// figure out what is the intended behavior.
BorrowKind::Shallow | BorrowKind::Unique => return Err(Unpromotable),
}

// We can only promote interior borrows of promotable temps (non-temps
// don't get promoted anyway).
self.validate_local(place.local)?;

// The reference operation itself must be promotable.
// (Needs to come after `validate_local` to avoid ICEs.)
self.validate_ref(*kind, place)?;

// We do not check all the projections (they do not get promoted anyway),
// but we do stay away from promoting anything involving a dereference.
if place.projection.contains(&ProjectionElem::Deref) {
return Err(Unpromotable);
}
if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
return Err(Unpromotable);
}

// FIXME(eddyb) this duplicates part of `validate_rvalue`.
let has_mut_interior =
self.qualif_local::<qualifs::HasMutInterior>(place.local);
if has_mut_interior {
// We cannot promote things that need dropping, since the promoted value
// would not get dropped.
if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
return Err(Unpromotable);
}

if let BorrowKind::Mut { .. } = kind {
let ty = place.ty(self.body, self.tcx).ty;

// In theory, any zero-sized value could be borrowed
// mutably without consequences. However, only &mut []
// is allowed right now.
if let ty::Array(_, len) = ty.kind() {
match len.try_eval_usize(self.tcx, self.param_env) {
Some(0) => {}
_ => return Err(Unpromotable),
}
} else {
return Err(Unpromotable);
}
}

Ok(())
}
_ => bug!(),
Expand Down Expand Up @@ -572,58 +548,115 @@ impl<'tcx> Validator<'_, 'tcx> {
}
}

fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
match *rvalue {
Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => {
let operand_ty = operand.ty(self.body, self.tcx);
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) {
// ptr-to-int casts are not possible in consts and thus not promotable
fn validate_ref(&self, kind: BorrowKind, place: &Place<'tcx>) -> Result<(), Unpromotable> {
match kind {
// Reject these borrow types just to be safe.
// FIXME(RalfJung): could we allow them? Should we? No point in it until we have a usecase.
BorrowKind::Shallow | BorrowKind::Unique => return Err(Unpromotable),

BorrowKind::Shared => {
let has_mut_interior = self.qualif_local::<qualifs::HasMutInterior>(place.local);
if has_mut_interior {
return Err(Unpromotable);
}
}

Rvalue::BinaryOp(op, ref lhs, _) => {
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind() {
assert!(
op == BinOp::Eq
|| op == BinOp::Ne
|| op == BinOp::Le
|| op == BinOp::Lt
|| op == BinOp::Ge
|| op == BinOp::Gt
|| op == BinOp::Offset
);
BorrowKind::Mut { .. } => {
let ty = place.ty(self.body, self.tcx).ty;

// raw pointer operations are not allowed inside consts and thus not promotable
// In theory, any zero-sized value could be borrowed
// mutably without consequences. However, only &mut []
// is allowed right now.
if let ty::Array(_, len) = ty.kind() {
match len.try_eval_usize(self.tcx, self.param_env) {
Some(0) => {}
_ => return Err(Unpromotable),
}
} else {
return Err(Unpromotable);
}
}

Rvalue::NullaryOp(NullOp::Box, _) => return Err(Unpromotable),

// FIXME(RalfJung): the rest is *implicitly considered promotable*... that seems dangerous.
_ => {}
}

Ok(())
}

fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
match rvalue {
Rvalue::ThreadLocalRef(_) => Err(Unpromotable),
Rvalue::Use(operand)
| Rvalue::Repeat(operand, _)
| Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, operand) => {
self.validate_operand(operand)?;
}

Rvalue::NullaryOp(..) => Ok(()),
Rvalue::Discriminant(place) | Rvalue::Len(place) => {
self.validate_place(place.as_ref())?
}

Rvalue::Discriminant(place) | Rvalue::Len(place) => self.validate_place(place.as_ref()),
Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),

Rvalue::Use(operand)
| Rvalue::Repeat(operand, _)
| Rvalue::UnaryOp(_, operand)
| Rvalue::Cast(_, operand, _) => self.validate_operand(operand),
Rvalue::Cast(kind, operand, cast_ty) => {
if matches!(kind, CastKind::Misc) {
let operand_ty = operand.ty(self.body, self.tcx);
let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) {
// ptr-to-int casts are not possible in consts and thus not promotable
return Err(Unpromotable);
}
// int-to-ptr casts are fine, they just use the integer value at pointer type.
}

self.validate_operand(operand)?;
}

Rvalue::BinaryOp(op, lhs, rhs) | Rvalue::CheckedBinaryOp(op, lhs, rhs) => {
let op = *op;
if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind() {
// raw pointer operations are not allowed inside consts and thus not promotable
assert!(matches!(
op,
BinOp::Eq
| BinOp::Ne
| BinOp::Le
| BinOp::Lt
| BinOp::Ge
| BinOp::Gt
| BinOp::Offset
));
return Err(Unpromotable);
}

match op {
// FIXME: reject operations that can fail -- namely, division and modulo.
BinOp::Eq
| BinOp::Ne
| BinOp::Le
| BinOp::Lt
| BinOp::Ge
| BinOp::Gt
| BinOp::Offset
| BinOp::Add
| BinOp::Sub
| BinOp::Mul
| BinOp::Div
| BinOp::Rem
| BinOp::BitXor
| BinOp::BitAnd
| BinOp::BitOr
| BinOp::Shl
| BinOp::Shr => {}
}

Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
self.validate_operand(lhs)?;
self.validate_operand(rhs)
self.validate_operand(rhs)?;
}

Rvalue::NullaryOp(op, _) => match op {
NullOp::Box => return Err(Unpromotable),
NullOp::SizeOf => {}
},

Rvalue::AddressOf(_, place) => {
// We accept `&raw *`, i.e., raw reborrows -- creating a raw pointer is
// no problem, only using it is.
Expand All @@ -636,53 +669,36 @@ impl<'tcx> Validator<'_, 'tcx> {
});
}
}
Err(Unpromotable)
return Err(Unpromotable);
}

Rvalue::Ref(_, kind, place) => {
if let BorrowKind::Mut { .. } = kind {
let ty = place.ty(self.body, self.tcx).ty;

// In theory, any zero-sized value could be borrowed
// mutably without consequences. However, only &mut []
// is allowed right now.
if let ty::Array(_, len) = ty.kind() {
match len.try_eval_usize(self.tcx, self.param_env) {
Some(0) => {}
_ => return Err(Unpromotable),
}
} else {
return Err(Unpromotable);
}
}

// Special-case reborrows to be more like a copy of the reference.
let mut place = place.as_ref();
if let [proj_base @ .., ProjectionElem::Deref] = &place.projection {
let base_ty = Place::ty_from(place.local, proj_base, self.body, self.tcx).ty;
let mut place_simplified = place.as_ref();
if let [proj_base @ .., ProjectionElem::Deref] = &place_simplified.projection {
let base_ty =
Place::ty_from(place_simplified.local, proj_base, self.body, self.tcx).ty;
if let ty::Ref(..) = base_ty.kind() {
place = PlaceRef { local: place.local, projection: proj_base };
place_simplified =
PlaceRef { local: place_simplified.local, projection: proj_base };
}
}

self.validate_place(place)?;

let has_mut_interior = self.qualif_local::<qualifs::HasMutInterior>(place.local);
if has_mut_interior {
return Err(Unpromotable);
}
self.validate_place(place_simplified)?;

Ok(())
// Check that the reference is fine (using the original place!).
// (Needs to come after `validate_place` to avoid ICEs.)
self.validate_ref(*kind, place)?;
}

Rvalue::Aggregate(_, ref operands) => {
Rvalue::Aggregate(_, operands) => {
for o in operands {
self.validate_operand(o)?;
}

Ok(())
}
}

Ok(())
}

fn validate_call(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,8 @@ struct SplitIntRange {
}

impl SplitIntRange {
fn new(r: IntRange) -> Self {
SplitIntRange { range: r.clone(), borders: Vec::new() }
fn new(range: IntRange) -> Self {
SplitIntRange { range, borders: Vec::new() }
}

/// Internal use
Expand Down
Loading