Skip to content

Commit 8f36334

Browse files
committed
Auto merge of #95742 - Dylan-DPC:rollup-8n7o87y, r=Dylan-DPC
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
2 parents c2afaba + ebba894 commit 8f36334

37 files changed

+402
-159
lines changed

.git-blame-ignore-revs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# format the world
2+
a06baa56b95674fc626b3c3fd680d6a65357fe60
3+
# format libcore
4+
95e00bfed801e264e9c4ac817004153ca0f19eb6
5+
# reformat with new rustfmt
6+
971c549ca334b7b7406e61e958efcca9c4152822

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+80-62
Original file line numberDiff line numberDiff line change
@@ -55,75 +55,93 @@ impl<'tcx> RegionInferenceContext<'tcx> {
5555
infcx: &InferCtxt<'_, 'tcx>,
5656
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
5757
) -> VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> {
58-
opaque_ty_decls
59-
.into_iter()
60-
.map(|(opaque_type_key, (concrete_type, origin))| {
61-
let substs = opaque_type_key.substs;
62-
debug!(?concrete_type, ?substs);
58+
let mut result: VecMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>> = VecMap::new();
59+
for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls {
60+
let substs = opaque_type_key.substs;
61+
debug!(?concrete_type, ?substs);
6362

64-
let mut subst_regions = vec![self.universal_regions.fr_static];
65-
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
66-
if let ty::RePlaceholder(..) = region.kind() {
67-
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
68-
return region;
63+
let mut subst_regions = vec![self.universal_regions.fr_static];
64+
let universal_substs = infcx.tcx.fold_regions(substs, &mut false, |region, _| {
65+
if let ty::RePlaceholder(..) = region.kind() {
66+
// Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs.
67+
return region;
68+
}
69+
let vid = self.to_region_vid(region);
70+
trace!(?vid);
71+
let scc = self.constraint_sccs.scc(vid);
72+
trace!(?scc);
73+
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
74+
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
75+
}) {
76+
Some(region) => {
77+
let vid = self.universal_regions.to_region_vid(region);
78+
subst_regions.push(vid);
79+
region
6980
}
70-
let vid = self.to_region_vid(region);
71-
trace!(?vid);
72-
let scc = self.constraint_sccs.scc(vid);
73-
trace!(?scc);
74-
match self.scc_values.universal_regions_outlived_by(scc).find_map(|lb| {
75-
self.eval_equal(vid, lb).then_some(self.definitions[lb].external_name?)
76-
}) {
77-
Some(region) => {
78-
let vid = self.universal_regions.to_region_vid(region);
79-
subst_regions.push(vid);
80-
region
81-
}
82-
None => {
83-
subst_regions.push(vid);
84-
infcx.tcx.sess.delay_span_bug(
85-
concrete_type.span,
86-
"opaque type with non-universal region substs",
87-
);
88-
infcx.tcx.lifetimes.re_static
89-
}
81+
None => {
82+
subst_regions.push(vid);
83+
infcx.tcx.sess.delay_span_bug(
84+
concrete_type.span,
85+
"opaque type with non-universal region substs",
86+
);
87+
infcx.tcx.lifetimes.re_static
9088
}
91-
});
89+
}
90+
});
9291

93-
subst_regions.sort();
94-
subst_regions.dedup();
92+
subst_regions.sort();
93+
subst_regions.dedup();
9594

96-
let universal_concrete_type =
97-
infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region {
98-
ty::ReVar(vid) => subst_regions
99-
.iter()
100-
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
101-
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
102-
.unwrap_or(infcx.tcx.lifetimes.re_root_empty),
103-
_ => region,
104-
});
95+
let universal_concrete_type =
96+
infcx.tcx.fold_regions(concrete_type, &mut false, |region, _| match *region {
97+
ty::ReVar(vid) => subst_regions
98+
.iter()
99+
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
100+
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)
101+
.unwrap_or(infcx.tcx.lifetimes.re_root_empty),
102+
_ => region,
103+
});
105104

106-
debug!(?universal_concrete_type, ?universal_substs);
105+
debug!(?universal_concrete_type, ?universal_substs);
107106

108-
let opaque_type_key =
109-
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
110-
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
111-
opaque_type_key,
112-
universal_concrete_type,
113-
);
114-
let ty = if check_opaque_type_parameter_valid(
115-
infcx.tcx,
116-
opaque_type_key,
117-
origin,
118-
concrete_type.span,
119-
) {
120-
remapped_type
121-
} else {
122-
infcx.tcx.ty_error()
123-
};
124-
(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span })
125-
})
126-
.collect()
107+
let opaque_type_key =
108+
OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs };
109+
let remapped_type = infcx.infer_opaque_definition_from_instantiation(
110+
opaque_type_key,
111+
universal_concrete_type,
112+
);
113+
let ty = if check_opaque_type_parameter_valid(
114+
infcx.tcx,
115+
opaque_type_key,
116+
origin,
117+
concrete_type.span,
118+
) {
119+
remapped_type
120+
} else {
121+
infcx.tcx.ty_error()
122+
};
123+
// Sometimes two opaque types are the same only after we remap the generic parameters
124+
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
125+
// and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
126+
// once we convert the generic parameters to those of the opaque type.
127+
if let Some(prev) = result.get_mut(&opaque_type_key) {
128+
if prev.ty != ty {
129+
let mut err = infcx.tcx.sess.struct_span_err(
130+
concrete_type.span,
131+
&format!("hidden type `{}` differed from previous `{}`", ty, prev.ty),
132+
);
133+
err.span_note(prev.span, "previous hidden type bound here");
134+
err.emit();
135+
prev.ty = infcx.tcx.ty_error();
136+
}
137+
// Pick a better span if there is one.
138+
// FIXME(oli-obk): collect multiple spans for better diagnostics down the road.
139+
prev.span = prev.span.substitute_dummy(concrete_type.span);
140+
} else {
141+
result.insert(opaque_type_key, OpaqueHiddenType { ty, span: concrete_type.span });
142+
}
143+
}
144+
result
127145
}
128146

129147
/// Map the regions in the type to named regions. This is similar to what
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use crate::MirPass;
2+
use rustc_middle::mir::patch::MirPatch;
3+
use rustc_middle::mir::*;
4+
use rustc_middle::ty::TyCtxt;
5+
pub struct Derefer;
6+
7+
pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
8+
let mut patch = MirPatch::new(body);
9+
let (basic_blocks, local_decl) = body.basic_blocks_and_local_decls_mut();
10+
for (block, data) in basic_blocks.iter_enumerated_mut() {
11+
for (i, stmt) in data.statements.iter_mut().enumerate() {
12+
match stmt.kind {
13+
StatementKind::Assign(box (og_place, Rvalue::Ref(region, borrow_knd, place))) => {
14+
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
15+
if p_elem == ProjectionElem::Deref && !p_ref.projection.is_empty() {
16+
// The type that we are derefing.
17+
let ty = p_ref.ty(local_decl, tcx).ty;
18+
let temp = patch.new_temp(ty, stmt.source_info.span);
19+
20+
// Because we are assigning this right before original statement
21+
// we are using index i of statement.
22+
let loc = Location { block: block, statement_index: i };
23+
patch.add_statement(loc, StatementKind::StorageLive(temp));
24+
25+
// We are adding current p_ref's projections to our
26+
// temp value.
27+
let deref_place =
28+
Place::from(p_ref.local).project_deeper(p_ref.projection, tcx);
29+
patch.add_assign(
30+
loc,
31+
Place::from(temp),
32+
Rvalue::Use(Operand::Move(deref_place)),
33+
);
34+
35+
// We are creating a place by using our temp value's location
36+
// and copying derefed values which we need to create new statement.
37+
let temp_place =
38+
Place::from(temp).project_deeper(&place.projection[idx..], tcx);
39+
let new_stmt = Statement {
40+
source_info: stmt.source_info,
41+
kind: StatementKind::Assign(Box::new((
42+
og_place,
43+
Rvalue::Ref(region, borrow_knd, temp_place),
44+
))),
45+
};
46+
47+
// Replace current statement with newly created one.
48+
*stmt = new_stmt;
49+
50+
// Since our job with the temp is done it should be gone
51+
let loc = Location { block: block, statement_index: i + 1 };
52+
patch.add_statement(loc, StatementKind::StorageDead(temp));
53+
54+
// As all projections are off the base projection, if there are
55+
// multiple derefs in the middle of projection, it might cause
56+
// unsoundness, to not let that happen we break the loop.
57+
break;
58+
}
59+
}
60+
}
61+
_ => (),
62+
}
63+
}
64+
}
65+
patch.apply(body);
66+
}
67+
68+
impl<'tcx> MirPass<'tcx> for Derefer {
69+
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
70+
deref_finder(tcx, body);
71+
}
72+
}

compiler/rustc_mir_transform/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ mod const_prop_lint;
5353
mod coverage;
5454
mod deaggregator;
5555
mod deduplicate_blocks;
56+
mod deref_separator;
5657
mod dest_prop;
5758
pub mod dump_mir;
5859
mod early_otherwise_branch;
@@ -431,6 +432,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc
431432
// `Deaggregator` is conceptually part of MIR building, some backends rely on it happening
432433
// and it can help optimizations.
433434
&deaggregator::Deaggregator,
435+
&deref_separator::Derefer,
434436
&Lint(const_prop_lint::ConstProp),
435437
];
436438

library/std/src/panicking.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::process;
2020
use crate::sync::atomic::{AtomicBool, Ordering};
2121
use crate::sys::stdio::panic_output;
2222
use crate::sys_common::backtrace;
23-
use crate::sys_common::rwlock::StaticRWLock;
23+
use crate::sys_common::rwlock::StaticRwLock;
2424
use crate::sys_common::thread_info;
2525
use crate::thread;
2626

@@ -83,7 +83,7 @@ impl Hook {
8383
}
8484
}
8585

86-
static HOOK_LOCK: StaticRWLock = StaticRWLock::new();
86+
static HOOK_LOCK: StaticRwLock = StaticRwLock::new();
8787
static mut HOOK: Hook = Hook::Default;
8888

8989
/// Registers a custom panic hook, replacing any that was previously registered.

library/std/src/sync/rwlock.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ use crate::sys_common::rwlock as sys;
7676
/// [`Mutex`]: super::Mutex
7777
#[stable(feature = "rust1", since = "1.0.0")]
7878
pub struct RwLock<T: ?Sized> {
79-
inner: sys::MovableRWLock,
79+
inner: sys::MovableRwLock,
8080
poison: poison::Flag,
8181
data: UnsafeCell<T>,
8282
}
@@ -146,7 +146,7 @@ impl<T> RwLock<T> {
146146
#[stable(feature = "rust1", since = "1.0.0")]
147147
pub fn new(t: T) -> RwLock<T> {
148148
RwLock {
149-
inner: sys::MovableRWLock::new(),
149+
inner: sys::MovableRwLock::new(),
150150
poison: poison::Flag::new(),
151151
data: UnsafeCell::new(t),
152152
}

library/std/src/sys/hermit/rwlock.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
use crate::cell::UnsafeCell;
22
use crate::sys::locks::{Condvar, Mutex};
33

4-
pub struct RWLock {
4+
pub struct RwLock {
55
lock: Mutex,
66
cond: Condvar,
77
state: UnsafeCell<State>,
88
}
99

10-
pub type MovableRWLock = RWLock;
10+
pub type MovableRwLock = RwLock;
1111

1212
enum State {
1313
Unlocked,
1414
Reading(usize),
1515
Writing,
1616
}
1717

18-
unsafe impl Send for RWLock {}
19-
unsafe impl Sync for RWLock {}
18+
unsafe impl Send for RwLock {}
19+
unsafe impl Sync for RwLock {}
2020

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

29-
impl RWLock {
30-
pub const fn new() -> RWLock {
31-
RWLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) }
29+
impl RwLock {
30+
pub const fn new() -> RwLock {
31+
RwLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) }
3232
}
3333

3434
#[inline]

library/std/src/sys/sgx/rwlock.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,25 @@ use super::waitqueue::{
88
};
99
use crate::mem;
1010

11-
pub struct RWLock {
11+
pub struct RwLock {
1212
readers: SpinMutex<WaitVariable<Option<NonZeroUsize>>>,
1313
writer: SpinMutex<WaitVariable<bool>>,
1414
}
1515

16-
pub type MovableRWLock = Box<RWLock>;
16+
pub type MovableRwLock = Box<RwLock>;
1717

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

27-
impl RWLock {
28-
pub const fn new() -> RWLock {
29-
RWLock {
27+
impl RwLock {
28+
pub const fn new() -> RwLock {
29+
RwLock {
3030
readers: SpinMutex::new(WaitVariable::new(None)),
3131
writer: SpinMutex::new(WaitVariable::new(false)),
3232
}
@@ -180,7 +180,7 @@ const EINVAL: i32 = 22;
180180

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

191191
#[cfg(not(test))]
192192
#[no_mangle]
193-
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
193+
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 {
194194
if p.is_null() {
195195
return EINVAL;
196196
}
@@ -199,7 +199,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
199199
}
200200
#[cfg(not(test))]
201201
#[no_mangle]
202-
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
202+
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 {
203203
if p.is_null() {
204204
return EINVAL;
205205
}

0 commit comments

Comments
 (0)