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 #61593

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Chris Thorn <chris@thorn.co> Chris Thorn <thorn@thoughtbot.com>
Chris Vittal <christopher.vittal@gmail.com> Christopher Vittal <christopher.vittal@gmail.com>
Christian Poveda <christianpoveda@protonmail.com> <cn.poveda.ruiz@gmail.com>
Christian Poveda <christianpoveda@protonmail.com> <z1mvader@protonmail.com>
Christian Poveda <christianpoveda@protonmail.com> <cpovedar@fnal.gov>
Clark Gaebel <cg.wowus.cg@gmail.com> <cgaebel@mozilla.com>
Clinton Ryan <clint.ryan3@gmail.com>
Corey Richardson <corey@octayn.net> Elaine "See More" Nemo <corey@octayn.net>
Expand Down Expand Up @@ -139,6 +140,7 @@ Kang Seonghoon <kang.seonghoon@mearie.org> <public+git@mearie.org>
Keegan McAllister <mcallister.keegan@gmail.com> <kmcallister@mozilla.com>
Kevin Butler <haqkrs@gmail.com>
Kyeongwoon Lee <kyeongwoon.lee@samsung.com>
Laurențiu Nicola <lnicola@dend.ro>
Lee Jeffery <leejeffery@gmail.com> Lee Jeffery <lee@leejeffery.co.uk>
Lee Wondong <wdlee91@gmail.com>
Lennart Kudling <github@kudling.de>
Expand Down
3 changes: 3 additions & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#![feature(arbitrary_self_types)]
#![feature(asm)]
#![feature(associated_type_defaults)]
#![feature(bound_cloned)]
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_fn)]
Expand Down Expand Up @@ -115,6 +116,8 @@
#![feature(wasm_target_feature)]
#![feature(avx512_target_feature)]
#![feature(cmpxchg16b_target_feature)]
#![feature(f16c_target_feature)]
#![feature(rtm_target_feature)]
#![feature(const_slice_len)]
#![feature(const_str_as_bytes)]
#![feature(const_str_len)]
Expand Down
23 changes: 23 additions & 0 deletions src/libcore/ops/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,29 @@ pub enum Bound<T> {
Unbounded,
}

impl<T: Clone> Bound<&T> {
/// Map a `Bound<&T>` to a `Bound<T>` by cloning the contents of the bound.
///
/// # Examples
///
/// ```
/// #![feature(bound_cloned)]
/// use std::ops::Bound::*;
/// use std::ops::RangeBounds;
///
/// assert_eq!((1..12).start_bound(), Included(&1));
/// assert_eq!((1..12).start_bound().cloned(), Included(1));
/// ```
#[unstable(feature = "bound_cloned", issue = "61356")]
pub fn cloned(self) -> Bound<T> {
match self {
Bound::Unbounded => Bound::Unbounded,
Bound::Included(x) => Bound::Included(x.clone()),
Bound::Excluded(x) => Bound::Excluded(x.clone()),
}
}
}

#[stable(feature = "collections_range", since = "1.28.0")]
/// `RangeBounds` is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
Expand Down
1 change: 1 addition & 0 deletions src/libcore/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![feature(bound_cloned)]
#![feature(box_syntax)]
#![feature(cell_update)]
#![feature(core_private_bignum)]
Expand Down
17 changes: 16 additions & 1 deletion src/libcore/tests/ops.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::ops::{Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
use core::ops::{Bound, Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};

// Test the Range structs without the syntactic sugar.

Expand Down Expand Up @@ -82,3 +82,18 @@ fn test_range_is_empty() {
assert!( (NAN ..= EPSILON).is_empty());
assert!( (NAN ..= NAN).is_empty());
}

#[test]
fn test_bound_cloned_unbounded() {
assert_eq!(Bound::<&u32>::Unbounded.cloned(), Bound::Unbounded);
}

#[test]
fn test_bound_cloned_included() {
assert_eq!(Bound::Included(&3).cloned(), Bound::Included(3));
}

#[test]
fn test_bound_cloned_excluded() {
assert_eq!(Bound::Excluded(&3).cloned(), Bound::Excluded(3));
}
85 changes: 48 additions & 37 deletions src/librustc_codegen_ssa/mir/analyze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,51 +154,62 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
context: PlaceContext,
location: Location) {
debug!("visit_place(place={:?}, context={:?})", place, context);
let mut context = context;
let cx = self.fx.cx;

if let mir::Place::Projection(ref proj) = *place {
// Allow uses of projections that are ZSTs or from scalar fields.
let is_consume = match context {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true,
_ => false
};
if is_consume {
let base_ty = proj.base.ty(self.fx.mir, cx.tcx());
let base_ty = self.fx.monomorphize(&base_ty);

// ZSTs don't require any actual memory access.
let elem_ty = base_ty
.projection_ty(cx.tcx(), &proj.elem)
.ty;
let elem_ty = self.fx.monomorphize(&elem_ty);
if cx.layout_of(elem_ty).is_zst() {
return;
}

if let mir::ProjectionElem::Field(..) = proj.elem {
let layout = cx.layout_of(base_ty.ty);
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `not_ssa` on locals.
self.visit_place(&proj.base, context, location);
place.iterate(|place_base, place_projections| {
for proj in place_projections {
// Allow uses of projections that are ZSTs or from scalar fields.
let is_consume = match context {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true,
_ => false
};
if is_consume {
let base_ty = proj.base.ty(self.fx.mir, cx.tcx());
let base_ty = self.fx.monomorphize(&base_ty);

// ZSTs don't require any actual memory access.
let elem_ty = base_ty
.projection_ty(cx.tcx(), &proj.elem)
.ty;
let elem_ty = self.fx.monomorphize(&elem_ty);
if cx.layout_of(elem_ty).is_zst() {
return;
}

if let mir::ProjectionElem::Field(..) = proj.elem {
let layout = cx.layout_of(base_ty.ty);
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
// Recurse with the same context, instead of `Projection`,
// potentially stopping at non-operand projections,
// which would trigger `not_ssa` on locals.
continue;
}
}
}
}

// A deref projection only reads the pointer, never needs the place.
if let mir::ProjectionElem::Deref = proj.elem {
return self.visit_place(
&proj.base,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
// A deref projection only reads the pointer, never needs the place.
if let mir::ProjectionElem::Deref = proj.elem {
return self.visit_place(
&proj.base,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
location
);
}

context = if context.is_mutating_use() {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
} else {
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
};
}
}

self.super_place(place, context, location);
// Default base visit behavior
if let mir::PlaceBase::Local(local) = place_base {
self.visit_local(local, context, location);
}
});
}

fn visit_local(&mut self,
Expand Down
79 changes: 39 additions & 40 deletions src/librustc_mir/transform/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,11 +199,39 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
fn visit_place(&mut self,
place: &Place<'tcx>,
context: PlaceContext,
location: Location) {
match place {
&Place::Projection(box Projection {
ref base, ref elem
}) => {
_location: Location) {
place.iterate(|place_base, place_projections| {
match place_base {
PlaceBase::Local(..) => {
// Locals are safe.
}
PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => {
bug!("unsafety checking should happen before promotion")
}
PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => {
if self.tcx.is_mutable_static(*def_id) {
self.require_unsafe("use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing \
violations or data races will cause undefined behavior",
UnsafetyViolationKind::General);
} else if self.tcx.is_foreign_item(*def_id) {
let source_info = self.source_info;
let lint_root =
self.source_scope_local_data[source_info.scope].lint_root;
self.register_violations(&[UnsafetyViolation {
source_info,
description: InternedString::intern("use of extern static"),
details: InternedString::intern(
"extern statics are not controlled by the Rust type system: \
invalid data, aliasing violations or data races will cause \
undefined behavior"),
kind: UnsafetyViolationKind::ExternStatic(lint_root)
}], &[]);
}
}
}

for proj in place_projections {
if context.is_borrow() {
if util::is_disaligned(self.tcx, self.mir, self.param_env, place) {
let source_info = self.source_info;
Expand All @@ -220,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
}], &[]);
}
}
let is_borrow_of_interior_mut = context.is_borrow() && !base
let is_borrow_of_interior_mut = context.is_borrow() && !proj.base
.ty(self.mir, self.tcx)
.ty
.is_freeze(self.tcx, self.param_env, self.source_info.span);
Expand All @@ -236,15 +264,15 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
);
}
let old_source_info = self.source_info;
if let &Place::Base(PlaceBase::Local(local)) = base {
if let Place::Base(PlaceBase::Local(local)) = proj.base {
if self.mir.local_decls[local].internal {
// Internal locals are used in the `move_val_init` desugaring.
// We want to check unsafety against the source info of the
// desugaring, rather than the source info of the RHS.
self.source_info = self.mir.local_decls[local].source_info;
}
}
let base_ty = base.ty(self.mir, self.tcx).ty;
let base_ty = proj.base.ty(self.mir, self.tcx).ty;
match base_ty.sty {
ty::RawPtr(..) => {
self.require_unsafe("dereference of raw pointer",
Expand All @@ -260,8 +288,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
MutatingUseContext::AsmOutput
)
{
let elem_ty = match elem {
&ProjectionElem::Field(_, ty) => ty,
let elem_ty = match proj.elem {
ProjectionElem::Field(_, ty) => ty,
_ => span_bug!(
self.source_info.span,
"non-field projection {:?} from union?",
Expand Down Expand Up @@ -292,36 +320,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
}
self.source_info = old_source_info;
}
&Place::Base(PlaceBase::Local(..)) => {
// locals are safe
}
&Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => {
bug!("unsafety checking should happen before promotion")
}
&Place::Base(
PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })
) => {
if self.tcx.is_mutable_static(def_id) {
self.require_unsafe("use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing violations \
or data races will cause undefined behavior",
UnsafetyViolationKind::General);
} else if self.tcx.is_foreign_item(def_id) {
let source_info = self.source_info;
let lint_root =
self.source_scope_local_data[source_info.scope].lint_root;
self.register_violations(&[UnsafetyViolation {
source_info,
description: InternedString::intern("use of extern static"),
details: InternedString::intern(
"extern statics are not controlled by the Rust type system: invalid \
data, aliasing violations or data races will cause undefined behavior"),
kind: UnsafetyViolationKind::ExternStatic(lint_root)
}], &[]);
}
}
};
self.super_place(place, context, location);
});
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/stdsimd