Auto merge of #61601 - Centril:rollup-uegbsns, r=Centril
Rollup of 5 pull requests Successful merges: - #61376 (Add Bound::cloned()) - #61554 (Change visit api) - #61559 (Make visitors iterate) - #61585 (Update .mailmap with my name) - #61591 (Update .mailmap) Failed merges: r? @ghost
This commit is contained in:
commit
5eeb567a27
2
.mailmap
2
.mailmap
@ -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>
|
||||
@ -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>
|
||||
|
@ -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)]
|
||||
|
@ -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`.
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![feature(bound_cloned)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_update)]
|
||||
#![feature(core_private_bignum)]
|
||||
|
@ -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.
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
@ -151,17 +151,17 @@ macro_rules! make_mir_visitor {
|
||||
self.super_place(place, context, location);
|
||||
}
|
||||
|
||||
fn visit_projection(&mut self,
|
||||
place: & $($mutability)? Projection<'tcx>,
|
||||
fn visit_place_base(&mut self,
|
||||
place_base: & $($mutability)? PlaceBase<'tcx>,
|
||||
context: PlaceContext,
|
||||
location: Location) {
|
||||
self.super_projection(place, context, location);
|
||||
self.super_place_base(place_base, context, location);
|
||||
}
|
||||
|
||||
fn visit_projection_elem(&mut self,
|
||||
place: & $($mutability)? PlaceElem<'tcx>,
|
||||
location: Location) {
|
||||
self.super_projection_elem(place, location);
|
||||
fn visit_projection(&mut self,
|
||||
place: & $($mutability)? Projection<'tcx>,
|
||||
location: Location) {
|
||||
self.super_projection(place, location);
|
||||
}
|
||||
|
||||
fn visit_constant(&mut self,
|
||||
@ -676,36 +676,40 @@ macro_rules! make_mir_visitor {
|
||||
context: PlaceContext,
|
||||
location: Location) {
|
||||
match place {
|
||||
Place::Base(PlaceBase::Local(local)) => {
|
||||
self.visit_local(local, context, location);
|
||||
}
|
||||
Place::Base(PlaceBase::Static(box Static { kind: _, ty })) => {
|
||||
self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
|
||||
Place::Base(place_base) => {
|
||||
self.visit_place_base(place_base, context, location);
|
||||
}
|
||||
Place::Projection(proj) => {
|
||||
self.visit_projection(proj, context, location);
|
||||
let context = if context.is_mutating_use() {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Projection)
|
||||
} else {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
|
||||
};
|
||||
|
||||
self.visit_place(& $($mutability)? proj.base, context, location);
|
||||
self.visit_projection(proj, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_place_base(&mut self,
|
||||
place_base: & $($mutability)? PlaceBase<'tcx>,
|
||||
context: PlaceContext,
|
||||
location: Location) {
|
||||
match place_base {
|
||||
PlaceBase::Local(local) => {
|
||||
self.visit_local(local, context, location);
|
||||
}
|
||||
PlaceBase::Static(box Static { kind: _, ty }) => {
|
||||
self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_projection(&mut self,
|
||||
proj: & $($mutability)? Projection<'tcx>,
|
||||
context: PlaceContext,
|
||||
location: Location) {
|
||||
let Projection { base, elem } = proj;
|
||||
let context = if context.is_mutating_use() {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Projection)
|
||||
} else {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
|
||||
};
|
||||
self.visit_place(base, context, location);
|
||||
self.visit_projection_elem(elem, location);
|
||||
}
|
||||
|
||||
fn super_projection_elem(&mut self,
|
||||
proj: & $($mutability)? PlaceElem<'tcx>,
|
||||
location: Location) {
|
||||
match proj {
|
||||
match & $($mutability)? proj.elem {
|
||||
ProjectionElem::Deref => {
|
||||
}
|
||||
ProjectionElem::Subslice { from: _, to: _ } => {
|
||||
|
@ -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);
|
||||
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.
|
||||
self.visit_place(&proj.base, context, location);
|
||||
// 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
|
||||
);
|
||||
}
|
||||
|
||||
context = if context.is_mutating_use() {
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Projection)
|
||||
} else {
|
||||
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
|
||||
};
|
||||
}
|
||||
|
||||
// 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
|
||||
);
|
||||
// Default base visit behavior
|
||||
if let mir::PlaceBase::Local(local) = place_base {
|
||||
self.visit_local(local, context, location);
|
||||
}
|
||||
}
|
||||
|
||||
self.super_place(place, context, location);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_local(&mut self,
|
||||
|
@ -185,7 +185,7 @@ use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance};
|
||||
use rustc::ty::print::obsolete::DefPathBasedNames;
|
||||
use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
|
||||
use rustc::session::config::EntryFnType;
|
||||
use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind};
|
||||
use rustc::mir::{self, Location, PlaceBase, Promoted, Static, StaticKind};
|
||||
use rustc::mir::visit::Visitor as MirVisitor;
|
||||
use rustc::mir::mono::{MonoItem, InstantiationMode};
|
||||
use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled};
|
||||
@ -655,14 +655,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
self.super_terminator_kind(kind, location);
|
||||
}
|
||||
|
||||
fn visit_place(&mut self,
|
||||
place: &mir::Place<'tcx>,
|
||||
context: mir::visit::PlaceContext,
|
||||
location: Location) {
|
||||
match place {
|
||||
Place::Base(
|
||||
PlaceBase::Static(box Static{ kind:StaticKind::Static(def_id), .. })
|
||||
) => {
|
||||
fn visit_place_base(&mut self,
|
||||
place_base: &mir::PlaceBase<'tcx>,
|
||||
_context: mir::visit::PlaceContext,
|
||||
location: Location) {
|
||||
match place_base {
|
||||
PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => {
|
||||
debug!("visiting static {:?} @ {:?}", def_id, location);
|
||||
|
||||
let tcx = self.tcx;
|
||||
@ -671,10 +669,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
self.output.push(MonoItem::Static(*def_id));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => {
|
||||
// FIXME: should we handle promoteds here instead of eagerly in collect_neighbours?
|
||||
}
|
||||
PlaceBase::Local(_) => {
|
||||
// Locals have no relevance for collector
|
||||
}
|
||||
}
|
||||
|
||||
self.super_place(place, context, location);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -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);
|
||||
@ -236,7 +264,7 @@ 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
|
||||
@ -244,7 +272,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
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",
|
||||
@ -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?",
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user