Skip to content

Commit 2fa4624

Browse files
committed
Auto merge of #63465 - Mark-Simulacrum:rollup-bq3u7tz, r=Mark-Simulacrum
Rollup of 8 pull requests Successful merges: - #61969 (Add #[repr(transparent)] for several types) - #62108 (Use sharded maps for queries) - #63149 (resolve: Populate external modules in more automatic and lazy way) - #63346 (Lint on some incorrect uses of mem::zeroed / mem::uninitialized) - #63433 (Miri shouldn't look at types) - #63440 (rename RUST_CTFE_BACKTRACE to RUSTC_CTFE_BACKTRACE) - #63442 (Add an example to show how to insert item to a sorted vec) - #63459 (syntax: account for CVarArgs being in the argument list.) Failed merges: r? @ghost
2 parents 8a06869 + 262394e commit 2fa4624

40 files changed

+655
-216
lines changed

src/libcore/mem/maybe_uninit.rs

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::mem::ManuallyDrop;
1313
/// ever gets used to access memory:
1414
///
1515
/// ```rust,no_run
16+
/// # #![allow(invalid_value)]
1617
/// use std::mem::{self, MaybeUninit};
1718
///
1819
/// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior!
@@ -27,6 +28,7 @@ use crate::mem::ManuallyDrop;
2728
/// always be `true` or `false`. Hence, creating an uninitialized `bool` is undefined behavior:
2829
///
2930
/// ```rust,no_run
31+
/// # #![allow(invalid_value)]
3032
/// use std::mem::{self, MaybeUninit};
3133
///
3234
/// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior!
@@ -40,6 +42,7 @@ use crate::mem::ManuallyDrop;
4042
/// which otherwise can hold any *fixed* bit pattern:
4143
///
4244
/// ```rust,no_run
45+
/// # #![allow(invalid_value)]
4346
/// use std::mem::{self, MaybeUninit};
4447
///
4548
/// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior!

src/libcore/mem/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,8 @@ pub const fn needs_drop<T>() -> bool {
445445
///
446446
/// *Incorrect* usage of this function: initializing a reference with zero.
447447
///
448-
/// ```no_run
448+
/// ```rust,no_run
449+
/// # #![allow(invalid_value)]
449450
/// use std::mem;
450451
///
451452
/// let _x: &i32 = unsafe { mem::zeroed() }; // Undefined behavior!

src/libcore/slice/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,17 @@ impl<T> [T] {
13641364
/// let r = s.binary_search(&1);
13651365
/// assert!(match r { Ok(1..=4) => true, _ => false, });
13661366
/// ```
1367+
///
1368+
/// If you want to insert an item to a sorted vector, while maintaining
1369+
/// sort order:
1370+
///
1371+
/// ```
1372+
/// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
1373+
/// let num = 42;
1374+
/// let idx = s.binary_search(&num).unwrap_or_else(|x| x);
1375+
/// s.insert(idx, num);
1376+
/// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
1377+
/// ```
13671378
#[stable(feature = "rust1", since = "1.0.0")]
13681379
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
13691380
where T: Ord

src/librustc/mir/interpret/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ fn print_backtrace(backtrace: &mut Backtrace) {
217217

218218
impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
219219
fn from(kind: InterpError<'tcx>) -> Self {
220-
let backtrace = match env::var("RUST_CTFE_BACKTRACE") {
220+
let backtrace = match env::var("RUSTC_CTFE_BACKTRACE") {
221221
// Matching `RUST_BACKTRACE` -- we treat "0" the same as "not present".
222222
Ok(ref val) if val != "0" => {
223223
let mut backtrace = Backtrace::new_unresolved();

src/librustc/ty/mod.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1842,7 +1842,8 @@ pub struct VariantDef {
18421842
pub ctor_kind: CtorKind,
18431843
/// Flags of the variant (e.g. is field list non-exhaustive)?
18441844
flags: VariantFlags,
1845-
/// Recovered?
1845+
/// Variant is obtained as part of recovering from a syntactic error.
1846+
/// May be incomplete or bogus.
18461847
pub recovered: bool,
18471848
}
18481849

@@ -1949,7 +1950,7 @@ pub struct FieldDef {
19491950
pub struct AdtDef {
19501951
/// `DefId` of the struct, enum or union item.
19511952
pub did: DefId,
1952-
/// Variants of the ADT. If this is a struct or enum, then there will be a single variant.
1953+
/// Variants of the ADT. If this is a struct or union, then there will be a single variant.
19531954
pub variants: IndexVec<self::layout::VariantIdx, VariantDef>,
19541955
/// Flags of the ADT (e.g. is this a struct? is this non-exhaustive?)
19551956
flags: AdtFlags,
@@ -2565,6 +2566,8 @@ impl<'tcx> AdtDef {
25652566
}
25662567

25672568
impl<'tcx> FieldDef {
2569+
/// Returns the type of this field. The `subst` is typically obtained
2570+
/// via the second field of `TyKind::AdtDef`.
25682571
pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
25692572
tcx.type_of(self.did).subst(tcx, subst)
25702573
}

src/librustc/ty/query/config.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::util::profiling::ProfileCategory;
1111
use std::borrow::Cow;
1212
use std::hash::Hash;
1313
use std::fmt::Debug;
14-
use rustc_data_structures::sync::Lock;
14+
use rustc_data_structures::sharded::Sharded;
1515
use rustc_data_structures::fingerprint::Fingerprint;
1616
use crate::ich::StableHashingContext;
1717

@@ -34,7 +34,7 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
3434
fn query(key: Self::Key) -> Query<'tcx>;
3535

3636
// Don't use this method to access query results, instead use the methods on TyCtxt
37-
fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Lock<QueryCache<'tcx, Self>>;
37+
fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Sharded<QueryCache<'tcx, Self>>;
3838

3939
fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;
4040

src/librustc/ty/query/on_disk_cache.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1062,9 +1062,9 @@ where
10621062
::std::any::type_name::<Q>());
10631063

10641064
time_ext(tcx.sess.time_extended(), Some(tcx.sess), desc, || {
1065-
let map = Q::query_cache(tcx).borrow();
1066-
assert!(map.active.is_empty());
1067-
for (key, entry) in map.results.iter() {
1065+
let shards = Q::query_cache(tcx).lock_shards();
1066+
assert!(shards.iter().all(|shard| shard.active.is_empty()));
1067+
for (key, entry) in shards.iter().flat_map(|shard| shard.results.iter()) {
10681068
if Q::cache_on_disk(tcx, key.clone(), Some(&entry.value)) {
10691069
let dep_node = SerializedDepNodeIndex::new(entry.index.index());
10701070

src/librustc/ty/query/plumbing.rs

+23-21
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use errors::Diagnostic;
1717
use errors::FatalError;
1818
use rustc_data_structures::fx::{FxHashMap};
1919
use rustc_data_structures::sync::{Lrc, Lock};
20+
use rustc_data_structures::sharded::Sharded;
2021
use rustc_data_structures::thin_vec::ThinVec;
2122
#[cfg(not(parallel_compiler))]
2223
use rustc_data_structures::cold_path;
@@ -90,7 +91,7 @@ macro_rules! profq_query_msg {
9091
/// A type representing the responsibility to execute the job in the `job` field.
9192
/// This will poison the relevant query if dropped.
9293
pub(super) struct JobOwner<'a, 'tcx, Q: QueryDescription<'tcx>> {
93-
cache: &'a Lock<QueryCache<'tcx, Q>>,
94+
cache: &'a Sharded<QueryCache<'tcx, Q>>,
9495
key: Q::Key,
9596
job: Lrc<QueryJob<'tcx>>,
9697
}
@@ -107,7 +108,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
107108
pub(super) fn try_get(tcx: TyCtxt<'tcx>, span: Span, key: &Q::Key) -> TryGetJob<'a, 'tcx, Q> {
108109
let cache = Q::query_cache(tcx);
109110
loop {
110-
let mut lock = cache.borrow_mut();
111+
let mut lock = cache.get_shard_by_value(key).lock();
111112
if let Some(value) = lock.results.get(key) {
112113
profq_msg!(tcx, ProfileQueriesMsg::CacheHit);
113114
tcx.sess.profiler(|p| p.record_query_hit(Q::NAME));
@@ -191,7 +192,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
191192

192193
let value = QueryValue::new(result.clone(), dep_node_index);
193194
{
194-
let mut lock = cache.borrow_mut();
195+
let mut lock = cache.get_shard_by_value(&key).lock();
195196
lock.active.remove(&key);
196197
lock.results.insert(key, value);
197198
}
@@ -215,7 +216,8 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
215216
#[cold]
216217
fn drop(&mut self) {
217218
// Poison the query so jobs waiting on it panic
218-
self.cache.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
219+
let shard = self.cache.get_shard_by_value(&self.key);
220+
shard.lock().active.insert(self.key.clone(), QueryResult::Poisoned);
219221
// Also signal the completion of the job, so waiters
220222
// will continue execution
221223
self.job.signal_complete();
@@ -708,7 +710,7 @@ macro_rules! define_queries_inner {
708710
use std::mem;
709711
#[cfg(parallel_compiler)]
710712
use ty::query::job::QueryResult;
711-
use rustc_data_structures::sync::Lock;
713+
use rustc_data_structures::sharded::Sharded;
712714
use crate::{
713715
rustc_data_structures::stable_hasher::HashStable,
714716
rustc_data_structures::stable_hasher::StableHasherResult,
@@ -740,18 +742,17 @@ macro_rules! define_queries_inner {
740742
pub fn collect_active_jobs(&self) -> Vec<Lrc<QueryJob<$tcx>>> {
741743
let mut jobs = Vec::new();
742744

743-
// We use try_lock here since we are only called from the
745+
// We use try_lock_shards here since we are only called from the
744746
// deadlock handler, and this shouldn't be locked.
745747
$(
746-
jobs.extend(
747-
self.$name.try_lock().unwrap().active.values().filter_map(|v|
748-
if let QueryResult::Started(ref job) = *v {
749-
Some(job.clone())
750-
} else {
751-
None
752-
}
753-
)
754-
);
748+
let shards = self.$name.try_lock_shards().unwrap();
749+
jobs.extend(shards.iter().flat_map(|shard| shard.active.values().filter_map(|v|
750+
if let QueryResult::Started(ref job) = *v {
751+
Some(job.clone())
752+
} else {
753+
None
754+
}
755+
)));
755756
)*
756757

757758
jobs
@@ -773,26 +774,27 @@ macro_rules! define_queries_inner {
773774

774775
fn stats<'tcx, Q: QueryConfig<'tcx>>(
775776
name: &'static str,
776-
map: &QueryCache<'tcx, Q>
777+
map: &Sharded<QueryCache<'tcx, Q>>,
777778
) -> QueryStats {
779+
let map = map.lock_shards();
778780
QueryStats {
779781
name,
780782
#[cfg(debug_assertions)]
781-
cache_hits: map.cache_hits,
783+
cache_hits: map.iter().map(|shard| shard.cache_hits).sum(),
782784
#[cfg(not(debug_assertions))]
783785
cache_hits: 0,
784786
key_size: mem::size_of::<Q::Key>(),
785787
key_type: type_name::<Q::Key>(),
786788
value_size: mem::size_of::<Q::Value>(),
787789
value_type: type_name::<Q::Value>(),
788-
entry_count: map.results.len(),
790+
entry_count: map.iter().map(|shard| shard.results.len()).sum(),
789791
}
790792
}
791793

792794
$(
793795
queries.push(stats::<queries::$name<'_>>(
794796
stringify!($name),
795-
&*self.$name.lock()
797+
&self.$name,
796798
));
797799
)*
798800

@@ -967,7 +969,7 @@ macro_rules! define_queries_inner {
967969
}
968970

969971
#[inline(always)]
970-
fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a Lock<QueryCache<$tcx, Self>> {
972+
fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a Sharded<QueryCache<$tcx, Self>> {
971973
&tcx.queries.$name
972974
}
973975

@@ -1099,7 +1101,7 @@ macro_rules! define_queries_struct {
10991101
providers: IndexVec<CrateNum, Providers<$tcx>>,
11001102
fallback_extern_providers: Box<Providers<$tcx>>,
11011103

1102-
$($(#[$attr])* $name: Lock<QueryCache<$tcx, queries::$name<$tcx>>>,)*
1104+
$($(#[$attr])* $name: Sharded<QueryCache<$tcx, queries::$name<$tcx>>>,)*
11031105
}
11041106
};
11051107
}

src/librustc/ty/sty.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ pub enum TyKind<'tcx> {
171171
Never,
172172

173173
/// A tuple type. For example, `(i32, bool)`.
174+
/// Use `TyS::tuple_fields` to iterate over the field types.
174175
Tuple(SubstsRef<'tcx>),
175176

176177
/// The projection of an associated type. For example,
@@ -1723,8 +1724,8 @@ impl<'tcx> TyS<'tcx> {
17231724
})
17241725
})
17251726
}
1726-
ty::Tuple(tys) => tys.iter().any(|ty| {
1727-
ty.expect_ty().conservative_is_privately_uninhabited(tcx)
1727+
ty::Tuple(..) => self.tuple_fields().any(|ty| {
1728+
ty.conservative_is_privately_uninhabited(tcx)
17281729
}),
17291730
ty::Array(ty, len) => {
17301731
match len.try_eval_usize(tcx, ParamEnv::empty()) {
@@ -2103,6 +2104,15 @@ impl<'tcx> TyS<'tcx> {
21032104
}
21042105
}
21052106

2107+
/// Iterates over tuple fields.
2108+
/// Panics when called on anything but a tuple.
2109+
pub fn tuple_fields(&self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> {
2110+
match self.sty {
2111+
Tuple(substs) => substs.iter().map(|field| field.expect_ty()),
2112+
_ => bug!("tuple_fields called on non-tuple"),
2113+
}
2114+
}
2115+
21062116
/// If the type contains variants, returns the valid range of variant indices.
21072117
/// FIXME This requires the optimized MIR in the case of generators.
21082118
#[inline]

src/librustc/ty/util.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -845,15 +845,15 @@ impl<'tcx> ty::TyS<'tcx> {
845845
ty: Ty<'tcx>,
846846
) -> Representability {
847847
match ty.sty {
848-
Tuple(ref ts) => {
848+
Tuple(..) => {
849849
// Find non representable
850-
fold_repr(ts.iter().map(|ty| {
850+
fold_repr(ty.tuple_fields().map(|ty| {
851851
is_type_structurally_recursive(
852852
tcx,
853853
sp,
854854
seen,
855855
representable_cache,
856-
ty.expect_ty(),
856+
ty,
857857
)
858858
}))
859859
}
@@ -1095,7 +1095,7 @@ fn needs_drop_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>
10951095
// state transformation pass
10961096
ty::Generator(..) => true,
10971097

1098-
ty::Tuple(ref tys) => tys.iter().map(|k| k.expect_ty()).any(needs_drop),
1098+
ty::Tuple(..) => ty.tuple_fields().any(needs_drop),
10991099

11001100
// unions don't have destructors because of the child types,
11011101
// only if they manually implement `Drop` (handled above).

src/librustc/ty/walk.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
119119
ty::GeneratorWitness(ts) => {
120120
stack.extend(ts.skip_binder().iter().cloned().rev());
121121
}
122-
ty::Tuple(ts) => {
123-
stack.extend(ts.iter().map(|k| k.expect_ty()).rev());
122+
ty::Tuple(..) => {
123+
stack.extend(parent_ty.tuple_fields().rev());
124124
}
125125
ty::FnDef(_, substs) => {
126126
stack.extend(substs.types().rev());

0 commit comments

Comments
 (0)