Skip to content

Commit

Permalink
Auto merge of #95742 - Dylan-DPC:rollup-8n7o87y, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 6 pull requests

Successful merges:

 - #95342 (Ignore "format the world" commit in git blame)
 - #95353 ([bootstrap] Give a hard error when filtering tests for a file that does not exist)
 - #95649 (New mir-opt deref_separator)
 - #95721 (Fix typo in bootstrap/setup.rs)
 - #95730 (Rename RWLock to RwLock in std::sys.)
 - #95731 (Check that all hidden types are the same and then deduplicate them.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Apr 6, 2022
2 parents c2afaba + ebba894 commit 8f36334
Show file tree
Hide file tree
Showing 37 changed files with 402 additions and 159 deletions.
6 changes: 6 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# format the world
a06baa56b95674fc626b3c3fd680d6a65357fe60
# format libcore
95e00bfed801e264e9c4ac817004153ca0f19eb6
# reformat with new rustfmt
971c549ca334b7b7406e61e958efcca9c4152822
142 changes: 80 additions & 62 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,75 +55,93 @@ impl<'tcx> RegionInferenceContext<'tcx> {
infcx: &InferCtxt<'_, 'tcx>,
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
) -> VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> {
opaque_ty_decls
.into_iter()
.map(|(opaque_type_key, (concrete_type, origin))| {
let substs = opaque_type_key.substs;
debug!(?concrete_type, ?substs);
let mut result: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> = VecMap::new();
for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
let substs = opaque_type_key.substs;
debug!(?concrete_type, ?substs);

let mut subst_regions = vec![self.universal_regions.fr_static];
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
if let ty::RePlaceholder(..) = region.kind() {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
return region;
let mut subst_regions = vec![self.universal_regions.fr_static];
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
if let ty::RePlaceholder(..) = region.kind() {
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
return region;
}
let vid = self.to_region_vid(region);
trace!(?vid);
let scc = self.constraint_sccs.scc(vid);
trace!(?scc);
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
}) {
Some(region) => {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
region
}
let vid = self.to_region_vid(region);
trace!(?vid);
let scc = self.constraint_sccs.scc(vid);
trace!(?scc);
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
}) {
Some(region) => {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
region
}
None => {
subst_regions.push(vid);
infcx.tcx.sess.delay_span_bug(
concrete_type.span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
}
None => {
subst_regions.push(vid);
infcx.tcx.sess.delay_span_bug(
concrete_type.span,
"opaque type with non-universal region substs",
);
infcx.tcx.lifetimes.re_static
}
});
}
});

subst_regions.sort();
subst_regions.dedup();
subst_regions.sort();
subst_regions.dedup();

let universal_concrete_type =
infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region {
ty::ReVar(vid) => subst_regions
.iter()
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
.unwrap_or(infcx.tcx.lifetimes.re_root_empty),
_ => region,
});
let universal_concrete_type =
infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region {
ty::ReVar(vid) => subst_regions
.iter()
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
.unwrap_or(infcx.tcx.lifetimes.re_root_empty),
_ => region,
});

debug!(?universal_concrete_type, ?universal_substs);
debug!(?universal_concrete_type, ?universal_substs);

let opaque_type_key =
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key,
universal_concrete_type,
);
let ty = if check_opaque_type_parameter_valid(
infcx.tcx,
opaque_type_key,
origin,
concrete_type.span,
) {
remapped_type
} else {
infcx.tcx.ty_error()
};
(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span })
})
.collect()
let opaque_type_key =
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key,
universal_concrete_type,
);
let ty = if check_opaque_type_parameter_valid(
infcx.tcx,
opaque_type_key,
origin,
concrete_type.span,
) {
remapped_type
} else {
infcx.tcx.ty_error()
};
// Sometimes two opaque types are the same only after we remap the generic parameters
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
// and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
// once we convert the generic parameters to those of the opaque type.
if let Some(prev) = result.get_mut(&opaque_type_key) {
if prev.ty != ty {
let mut err = infcx.tcx.sess.struct_span_err(
concrete_type.span,
&format!("hidden type `{}` differed from previous `{}`", ty, prev.ty),
);
err.span_note(prev.span, "previous hidden type bound here");
err.emit();
prev.ty = infcx.tcx.ty_error();
}
// Pick a better span if there is one.
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
prev.span = prev.span.substitute_dummy(concrete_type.span);
} else {
result.insert(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span });
}
}
result
}

/// Map the regions in the type to named regions. This is similar to what
Expand Down
72 changes: 72 additions & 0 deletions compiler/rustc_mir_transform/src/deref_separator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use crate::MirPass;
use rustc_middle::mir::patch::MirPatch;
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
pub struct Derefer;

pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mut patch = MirPatch::new(body);
let (basic_blocks, local_decl) = body.basic_blocks_and_local_decls_mut();
for (block, data) in basic_blocks.iter_enumerated_mut() {
for (i, stmt) in data.statements.iter_mut().enumerate() {
match stmt.kind {
StatementKind::Assign(box (og_place, Rvalue::Ref(region, borrow_knd, place))) => {
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
// The type that we are derefing.
let ty = p_ref.ty(local_decl, tcx).ty;
let temp = patch.new_temp(ty, stmt.source_info.span);

// Because we are assigning this right before original statement
// we are using index i of statement.
let loc = Location { block: block, statement_index: i };
patch.add_statement(loc, StatementKind::StorageLive(temp));

// We are adding current p_ref's projections to our
// temp value.
let deref_place =
Place::from(p_ref.local).project_deeper(p_ref.projection, tcx);
patch.add_assign(
loc,
Place::from(temp),
Rvalue::Use(Operand::Move(deref_place)),
);

// We are creating a place by using our temp value's location
// and copying derefed values which we need to create new statement.
let temp_place =
Place::from(temp).project_deeper(&place.projection[idx..], tcx);
let new_stmt = Statement {
source_info: stmt.source_info,
kind: StatementKind::Assign(Box::new((
og_place,
Rvalue::Ref(region, borrow_knd, temp_place),
))),
};

// Replace current statement with newly created one.
*stmt = new_stmt;

// Since our job with the temp is done it should be gone
let loc = Location { block: block, statement_index: i + 1 };
patch.add_statement(loc, StatementKind::StorageDead(temp));

// As all projections are off the base projection, if there are
// multiple derefs in the middle of projection, it might cause
// unsoundness, to not let that happen we break the loop.
break;
}
}
}
_ => (),
}
}
}
patch.apply(body);
}

impl<'tcx> MirPass<'tcx> for Derefer {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
deref_finder(tcx, body);
}
}
2 changes: 2 additions & 0 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ mod const_prop_lint;
mod coverage;
mod deaggregator;
mod deduplicate_blocks;
mod deref_separator;
mod dest_prop;
pub mod dump_mir;
mod early_otherwise_branch;
Expand Down Expand Up @@ -431,6 +432,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
// `Deaggregator` is conceptually part of MIR building, some backends rely on it happening
// and it can help optimizations.
&deaggregator::Deaggregator,
&deref_separator::Derefer,
&Lint(const_prop_lint::ConstProp),
];

Expand Down
4 changes: 2 additions & 2 deletions library/std/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::process;
use crate::sync::atomic::{AtomicBool, Ordering};
use crate::sys::stdio::panic_output;
use crate::sys_common::backtrace;
use crate::sys_common::rwlock::StaticRWLock;
use crate::sys_common::rwlock::StaticRwLock;
use crate::sys_common::thread_info;
use crate::thread;

Expand Down Expand Up @@ -83,7 +83,7 @@ impl Hook {
}
}

static HOOK_LOCK: StaticRWLock = StaticRWLock::new();
static HOOK_LOCK: StaticRwLock = StaticRwLock::new();
static mut HOOK: Hook = Hook::Default;

/// Registers a custom panic hook, replacing any that was previously registered.
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sync/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ use crate::sys_common::rwlock as sys;
/// [`Mutex`]: super::Mutex
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RwLock<T: ?Sized> {
inner: sys::MovableRWLock,
inner: sys::MovableRwLock,
poison: poison::Flag,
data: UnsafeCell<T>,
}
Expand Down Expand Up @@ -146,7 +146,7 @@ impl<T> RwLock<T> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(t: T) -> RwLock<T> {
RwLock {
inner: sys::MovableRWLock::new(),
inner: sys::MovableRwLock::new(),
poison: poison::Flag::new(),
data: UnsafeCell::new(t),
}
Expand Down
14 changes: 7 additions & 7 deletions library/std/src/sys/hermit/rwlock.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
use crate::cell::UnsafeCell;
use crate::sys::locks::{Condvar, Mutex};

pub struct RWLock {
pub struct RwLock {
lock: Mutex,
cond: Condvar,
state: UnsafeCell<State>,
}

pub type MovableRWLock = RWLock;
pub type MovableRwLock = RwLock;

enum State {
Unlocked,
Reading(usize),
Writing,
}

unsafe impl Send for RWLock {}
unsafe impl Sync for RWLock {}
unsafe impl Send for RwLock {}
unsafe impl Sync for RwLock {}

// This rwlock implementation is a relatively simple implementation which has a
// condition variable for readers/writers as well as a mutex protecting the
Expand All @@ -26,9 +26,9 @@ unsafe impl Sync for RWLock {}
// hopefully correct this implementation is very likely to want to be changed in
// the future.

impl RWLock {
pub const fn new() -> RWLock {
RWLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) }
impl RwLock {
pub const fn new() -> RwLock {
RwLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) }
}

#[inline]
Expand Down
22 changes: 11 additions & 11 deletions library/std/src/sys/sgx/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,25 @@ use super::waitqueue::{
};
use crate::mem;

pub struct RWLock {
pub struct RwLock {
readers: SpinMutex<WaitVariable<Option<NonZeroUsize>>>,
writer: SpinMutex<WaitVariable<bool>>,
}

pub type MovableRWLock = Box<RWLock>;
pub type MovableRwLock = Box<RwLock>;

// Check at compile time that RWLock size matches C definition (see test_c_rwlock_initializer below)
// Check at compile time that RwLock size matches C definition (see test_c_rwlock_initializer below)
//
// # Safety
// Never called, as it is a compile time check.
#[allow(dead_code)]
unsafe fn rw_lock_size_assert(r: RWLock) {
unsafe { mem::transmute::<RWLock, [u8; 144]>(r) };
unsafe fn rw_lock_size_assert(r: RwLock) {
unsafe { mem::transmute::<RwLock, [u8; 144]>(r) };
}

impl RWLock {
pub const fn new() -> RWLock {
RWLock {
impl RwLock {
pub const fn new() -> RwLock {
RwLock {
readers: SpinMutex::new(WaitVariable::new(None)),
writer: SpinMutex::new(WaitVariable::new(false)),
}
Expand Down Expand Up @@ -180,7 +180,7 @@ const EINVAL: i32 = 22;

#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 {
if p.is_null() {
return EINVAL;
}
Expand All @@ -190,7 +190,7 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {

#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 {
if p.is_null() {
return EINVAL;
}
Expand All @@ -199,7 +199,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
}
#[cfg(not(test))]
#[no_mangle]
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 {
if p.is_null() {
return EINVAL;
}
Expand Down
Loading

0 comments on commit 8f36334

Please sign in to comment.