Skip to content

Commit c8551d3

Browse files
committed
Auto merge of #148938 - Zalathar:rollup-xg51707, r=Zalathar
Rollup of 4 pull requests Successful merges: - #148638 (Fix ICE for repr simd on non struct) - #148725 (Implement the alternative `try` block desugaring) - #148777 (Lock shards while emitting depth limit error.) - #148933 (Add note for option llvm.download-ci-llvm) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c880acd + 33eb5c2 commit c8551d3

File tree

20 files changed

+184
-49
lines changed

20 files changed

+184
-49
lines changed

bootstrap.example.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@
5959
# toolchain or changing LLVM locally, you probably want to leave this enabled.
6060
#
6161
# Set this to `true` to download if CI llvm available otherwise it builds
62-
# from `src/llvm-project`.
62+
# from `src/llvm-project`. If you set it to `true`, it's safe and time-saving to run
63+
# `git submodule deinit src/llvm-project` to avoid git updating the llvm-project submodule
64+
# when building compiler locally.
65+
#
6366
#
6467
# Set this to `"if-unchanged"` to download only if the llvm-project has not
6568
# been modified. You can also use this if you are unsure whether you're on a

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1929,7 +1929,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
19291929
/// ControlFlow::Break(residual) =>
19301930
/// #[allow(unreachable_code)]
19311931
/// // If there is an enclosing `try {...}`:
1932-
/// break 'catch_target Try::from_residual(residual),
1932+
/// break 'catch_target Residual::into_try_type(residual),
19331933
/// // Otherwise:
19341934
/// return Try::from_residual(residual),
19351935
/// }
@@ -1979,7 +1979,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
19791979
let (residual_local, residual_local_nid) = self.pat_ident(try_span, residual_ident);
19801980
let residual_expr = self.expr_ident_mut(try_span, residual_ident, residual_local_nid);
19811981
let from_residual_expr = self.wrap_in_try_constructor(
1982-
hir::LangItem::TryTraitFromResidual,
1982+
if self.catch_scope.is_some() {
1983+
hir::LangItem::ResidualIntoTryType
1984+
} else {
1985+
hir::LangItem::TryTraitFromResidual
1986+
},
19831987
try_span,
19841988
self.arena.alloc(residual_expr),
19851989
unstable_span,

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
183183
impl_trait_defs: Vec::new(),
184184
impl_trait_bounds: Vec::new(),
185185
allow_contracts: [sym::contracts_internals].into(),
186-
allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
186+
allow_try_trait: [
187+
sym::try_trait_v2,
188+
sym::try_trait_v2_residual,
189+
sym::yeet_desugar_details,
190+
]
191+
.into(),
187192
allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
188193
allow_gen_future: if tcx.features().async_fn_track_caller() {
189194
[sym::gen_future, sym::closure_track_caller].into()

compiler/rustc_hir/src/lang_items.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ language_item_table! {
370370
TryTraitFromOutput, sym::from_output, from_output_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
371371
TryTraitBranch, sym::branch, branch_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
372372
TryTraitFromYeet, sym::from_yeet, from_yeet_fn, Target::Fn, GenericRequirement::None;
373+
ResidualIntoTryType, sym::into_try_type, into_try_type_fn, Target::Fn, GenericRequirement::None;
373374

374375
CoercePointeeValidated, sym::coerce_pointee_validated, coerce_pointee_validated_trait, Target::Trait, GenericRequirement::Exact(0);
375376

compiler/rustc_hir_typeck/src/inline_asm.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_middle::bug;
77
use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
88
use rustc_session::lint;
99
use rustc_span::def_id::LocalDefId;
10-
use rustc_span::{Span, Symbol, sym};
10+
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
1111
use rustc_target::asm::{
1212
InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo,
1313
};
@@ -27,6 +27,7 @@ enum NonAsmTypeReason<'tcx> {
2727
InvalidElement(DefId, Ty<'tcx>),
2828
NotSizedPtr(Ty<'tcx>),
2929
EmptySIMDArray(Ty<'tcx>),
30+
Tainted(ErrorGuaranteed),
3031
}
3132

3233
impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
@@ -93,6 +94,14 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
9394
}
9495
}
9596
ty::Adt(adt, args) if adt.repr().simd() => {
97+
if !adt.is_struct() {
98+
let guar = self.fcx.dcx().span_delayed_bug(
99+
span,
100+
format!("repr(simd) should only be used on structs, got {}", adt.descr()),
101+
);
102+
return Err(NonAsmTypeReason::Tainted(guar));
103+
}
104+
96105
let fields = &adt.non_enum_variant().fields;
97106
if fields.is_empty() {
98107
return Err(NonAsmTypeReason::EmptySIMDArray(ty));
@@ -234,6 +243,9 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
234243
let msg = format!("use of empty SIMD vector `{ty}`");
235244
self.fcx.dcx().struct_span_err(expr.span, msg).emit();
236245
}
246+
NonAsmTypeReason::Tainted(_error_guard) => {
247+
// An error has already been reported.
248+
}
237249
}
238250
return None;
239251
}

compiler/rustc_interface/src/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ pub(crate) fn run_in_thread_pool_with_globals<
252252
let query_map = rustc_span::set_session_globals_then(unsafe { &*(session_globals as *const SessionGlobals) }, || {
253253
// Ensure there was no errors collecting all active jobs.
254254
// We need the complete map to ensure we find a cycle to break.
255-
QueryCtxt::new(tcx).collect_active_jobs().expect("failed to collect active queries in deadlock handler")
255+
QueryCtxt::new(tcx).collect_active_jobs(false).expect("failed to collect active queries in deadlock handler")
256256
});
257257
break_query_cycles(query_map, &registry);
258258
})

compiler/rustc_query_impl/src/plumbing.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,25 @@ impl<'tcx> QueryContext for QueryCtxt<'tcx> {
8888
tls::with_related_context(self.tcx, |icx| icx.query)
8989
}
9090

91-
/// Returns a query map representing active query jobs.
92-
/// It returns an incomplete map as an error if it fails
93-
/// to take locks.
91+
/// Returns a map of currently active query jobs.
92+
///
93+
/// If `require_complete` is `true`, this function locks all shards of the
94+
/// query results to produce a complete map, which always returns `Ok`.
95+
/// Otherwise, it may return an incomplete map as an error if any shard
96+
/// lock cannot be acquired.
97+
///
98+
/// Prefer passing `false` to `require_complete` to avoid potential deadlocks,
99+
/// especially when called from within a deadlock handler, unless a
100+
/// complete map is needed and no deadlock is possible at this call site.
94101
fn collect_active_jobs(
95102
self,
103+
require_complete: bool,
96104
) -> Result<QueryMap<QueryStackDeferred<'tcx>>, QueryMap<QueryStackDeferred<'tcx>>> {
97105
let mut jobs = QueryMap::default();
98106
let mut complete = true;
99107

100-
for collect in super::TRY_COLLECT_ACTIVE_JOBS.iter() {
101-
if collect(self.tcx, &mut jobs).is_none() {
108+
for collect in super::COLLECT_ACTIVE_JOBS.iter() {
109+
if collect(self.tcx, &mut jobs, require_complete).is_none() {
102110
complete = false;
103111
}
104112
}
@@ -163,11 +171,7 @@ impl<'tcx> QueryContext for QueryCtxt<'tcx> {
163171
}
164172

165173
fn depth_limit_error(self, job: QueryJobId) {
166-
// FIXME: `collect_active_jobs` expects no locks to be held, which doesn't hold for this call.
167-
let query_map = match self.collect_active_jobs() {
168-
Ok(query_map) => query_map,
169-
Err(query_map) => query_map,
170-
};
174+
let query_map = self.collect_active_jobs(true).expect("failed to collect active queries");
171175
let (info, depth) = job.find_dep_kind_root(query_map);
172176

173177
let suggested_limit = match self.recursion_limit() {
@@ -731,19 +735,21 @@ macro_rules! define_queries {
731735
}
732736
}
733737

734-
pub(crate) fn try_collect_active_jobs<'tcx>(
738+
pub(crate) fn collect_active_jobs<'tcx>(
735739
tcx: TyCtxt<'tcx>,
736740
qmap: &mut QueryMap<QueryStackDeferred<'tcx>>,
741+
require_complete: bool,
737742
) -> Option<()> {
738743
let make_query = |tcx, key| {
739744
let kind = rustc_middle::dep_graph::dep_kinds::$name;
740745
let name = stringify!($name);
741746
$crate::plumbing::create_query_frame(tcx, rustc_middle::query::descs::$name, key, kind, name)
742747
};
743-
let res = tcx.query_system.states.$name.try_collect_active_jobs(
748+
let res = tcx.query_system.states.$name.collect_active_jobs(
744749
tcx,
745750
make_query,
746751
qmap,
752+
require_complete,
747753
);
748754
// this can be called during unwinding, and the function has a `try_`-prefix, so
749755
// don't `unwrap()` here, just manually check for `None` and do best-effort error
@@ -814,10 +820,10 @@ macro_rules! define_queries {
814820

815821
// These arrays are used for iteration and can't be indexed by `DepKind`.
816822

817-
const TRY_COLLECT_ACTIVE_JOBS: &[
818-
for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap<QueryStackDeferred<'tcx>>) -> Option<()>
823+
const COLLECT_ACTIVE_JOBS: &[
824+
for<'tcx> fn(TyCtxt<'tcx>, &mut QueryMap<QueryStackDeferred<'tcx>>, bool) -> Option<()>
819825
] =
820-
&[$(query_impl::$name::try_collect_active_jobs),*];
826+
&[$(query_impl::$name::collect_active_jobs),*];
821827

822828
const ALLOC_SELF_PROFILE_QUERY_STRINGS: &[
823829
for<'tcx> fn(TyCtxt<'tcx>, &mut QueryKeyStringCache)

compiler/rustc_query_system/src/query/job.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ pub fn print_query_stack<Qcx: QueryContext>(
616616
let mut count_total = 0;
617617

618618
// Make use of a partial query map if we fail to take locks collecting active queries.
619-
let query_map = match qcx.collect_active_jobs() {
619+
let query_map = match qcx.collect_active_jobs(false) {
620620
Ok(query_map) => query_map,
621621
Err(query_map) => query_map,
622622
};

compiler/rustc_query_system/src/query/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,10 @@ pub trait QueryContext: HasDepContext {
161161
/// Get the query information from the TLS context.
162162
fn current_query_job(self) -> Option<QueryJobId>;
163163

164-
fn collect_active_jobs(self) -> Result<QueryMap<Self::QueryInfo>, QueryMap<Self::QueryInfo>>;
164+
fn collect_active_jobs(
165+
self,
166+
require_complete: bool,
167+
) -> Result<QueryMap<Self::QueryInfo>, QueryMap<Self::QueryInfo>>;
165168

166169
fn lift_query_info(self, info: &Self::QueryInfo) -> QueryStackFrameExtra;
167170

compiler/rustc_query_system/src/query/plumbing.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ use std::fmt::Debug;
77
use std::hash::Hash;
88
use std::mem;
99

10+
use hashbrown::HashTable;
1011
use hashbrown::hash_table::Entry;
1112
use rustc_data_structures::fingerprint::Fingerprint;
1213
use rustc_data_structures::sharded::{self, Sharded};
1314
use rustc_data_structures::stack::ensure_sufficient_stack;
15+
use rustc_data_structures::sync::LockGuard;
1416
use rustc_data_structures::{outline, sync};
1517
use rustc_errors::{Diag, FatalError, StashKey};
1618
use rustc_span::{DUMMY_SP, Span};
@@ -63,22 +65,33 @@ where
6365
self.active.lock_shards().all(|shard| shard.is_empty())
6466
}
6567

66-
pub fn try_collect_active_jobs<Qcx: Copy>(
68+
pub fn collect_active_jobs<Qcx: Copy>(
6769
&self,
6870
qcx: Qcx,
6971
make_query: fn(Qcx, K) -> QueryStackFrame<I>,
7072
jobs: &mut QueryMap<I>,
73+
require_complete: bool,
7174
) -> Option<()> {
7275
let mut active = Vec::new();
7376

74-
// We use try_lock_shards here since we are called from the
75-
// deadlock handler, and this shouldn't be locked.
76-
for shard in self.active.try_lock_shards() {
77-
for (k, v) in shard?.iter() {
77+
let mut collect = |iter: LockGuard<'_, HashTable<(K, QueryResult<I>)>>| {
78+
for (k, v) in iter.iter() {
7879
if let QueryResult::Started(ref job) = *v {
79-
active.push((*k, (*job).clone()));
80+
active.push((*k, job.clone()));
8081
}
8182
}
83+
};
84+
85+
if require_complete {
86+
for shard in self.active.lock_shards() {
87+
collect(shard);
88+
}
89+
} else {
90+
// We use try_lock_shards here since we are called from the
91+
// deadlock handler, and this shouldn't be locked.
92+
for shard in self.active.try_lock_shards() {
93+
collect(shard?);
94+
}
8295
}
8396

8497
// Call `make_query` while we're not holding a `self.active` lock as `make_query` may call
@@ -271,7 +284,7 @@ where
271284
{
272285
// Ensure there was no errors collecting all active jobs.
273286
// We need the complete map to ensure we find a cycle to break.
274-
let query_map = qcx.collect_active_jobs().ok().expect("failed to collect active queries");
287+
let query_map = qcx.collect_active_jobs(false).ok().expect("failed to collect active queries");
275288

276289
let error = try_execute.find_cycle_in_stack(query_map, &qcx.current_query_job(), span);
277290
(mk_cycle(query, qcx, error.lift(qcx)), None)

0 commit comments

Comments
 (0)