Skip to content

Commit 620e36a

Browse files
committed
Auto merge of #153846 - Zalathar:rollup-pGGSemr, r=Zalathar
Rollup of 7 pull requests Successful merges: - #152621 (LinkedGraph: support adding nodes and edges in arbitrary order) - #153376 (Replace `visit_waiters` with `abstracted_waiters_of`) - #153760 (Move and expand the big `rustc_query_impl` macro into a physical `query_impl.rs`) - #153818 (Reimplement const closures) - #153774 (Fix std doctest build for SGX target.) - #153786 (Remove `value_from_cycle_error` specializations) - #153819 (delete some duplicated tests)
2 parents a0e206b + 00ae089 commit 620e36a

File tree

61 files changed

+610
-762
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+610
-762
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
230230
e.id,
231231
expr_hir_id,
232232
*coroutine_kind,
233+
*constness,
233234
fn_decl,
234235
body,
235236
*fn_decl_span,
@@ -1060,7 +1061,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10601061
binder: &ClosureBinder,
10611062
capture_clause: CaptureBy,
10621063
closure_id: NodeId,
1063-
constness: Const,
1064+
mut constness: Const,
10641065
movability: Movability,
10651066
decl: &FnDecl,
10661067
body: &Expr,
@@ -1070,11 +1071,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
10701071
let closure_def_id = self.local_def_id(closure_id);
10711072
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
10721073

1074+
if let Const::Yes(span) = constness {
1075+
if !self.is_in_const_context {
1076+
self.dcx().span_err(span, "cannot use `const` closures outside of const contexts");
1077+
constness = Const::No;
1078+
}
1079+
}
1080+
10731081
let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| {
10741082
let mut coroutine_kind = find_attr!(attrs, Coroutine(_) => hir::CoroutineKind::Coroutine(Movability::Movable));
10751083

10761084
// FIXME(contracts): Support contracts on closures?
1077-
let body_id = this.lower_fn_body(decl, None, |this| {
1085+
let body_id = this.lower_fn_body(decl, None, constness, |this| {
10781086
this.coroutine_kind = coroutine_kind;
10791087
let e = this.lower_expr_mut(body);
10801088
coroutine_kind = this.coroutine_kind;
@@ -1157,6 +1165,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11571165
closure_id: NodeId,
11581166
closure_hir_id: HirId,
11591167
coroutine_kind: CoroutineKind,
1168+
constness: Const,
11601169
decl: &FnDecl,
11611170
body: &Expr,
11621171
fn_decl_span: Span,
@@ -1203,6 +1212,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
12031212
let fn_decl =
12041213
self.lower_fn_decl(&decl, closure_id, fn_decl_span, FnDeclKind::Closure, None);
12051214

1215+
if let Const::Yes(span) = constness {
1216+
self.dcx().span_err(span, "const coroutines are not supported");
1217+
}
1218+
12061219
let c = self.arena.alloc(hir::Closure {
12071220
def_id: closure_def_id,
12081221
binder: binder_clause,
@@ -1216,7 +1229,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12161229
// knows that a `FnDecl` output type like `-> &str` actually means
12171230
// "coroutine that returns &str", rather than directly returning a `&str`.
12181231
kind: hir::ClosureKind::CoroutineClosure(coroutine_desugaring),
1219-
constness: hir::Constness::NotConst,
1232+
constness: self.lower_constness(constness),
12201233
});
12211234
hir::ExprKind::Closure(c)
12221235
}

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::mem;
2+
13
use rustc_abi::ExternAbi;
24
use rustc_ast::visit::AssocCtxt;
35
use rustc_ast::*;
@@ -345,6 +347,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
345347
body.as_deref(),
346348
attrs,
347349
contract.as_deref(),
350+
header.constness,
348351
);
349352

350353
let itctx = ImplTraitContext::Universal;
@@ -1024,6 +1027,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10241027
Some(body),
10251028
attrs,
10261029
contract.as_deref(),
1030+
sig.header.constness,
10271031
);
10281032
let (generics, sig) = self.lower_method_sig(
10291033
generics,
@@ -1217,6 +1221,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12171221
body.as_deref(),
12181222
attrs,
12191223
contract.as_deref(),
1224+
sig.header.constness,
12201225
);
12211226
let (generics, sig) = self.lower_method_sig(
12221227
generics,
@@ -1346,11 +1351,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
13461351
f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
13471352
) -> hir::BodyId {
13481353
let prev_coroutine_kind = self.coroutine_kind.take();
1354+
let prev_is_in_const_context = mem::take(&mut self.is_in_const_context);
13491355
let task_context = self.task_context.take();
13501356
let (parameters, result) = f(self);
13511357
let body_id = self.record_body(parameters, result);
13521358
self.task_context = task_context;
13531359
self.coroutine_kind = prev_coroutine_kind;
1360+
self.is_in_const_context = prev_is_in_const_context;
13541361
body_id
13551362
}
13561363

@@ -1369,9 +1376,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
13691376
&mut self,
13701377
decl: &FnDecl,
13711378
contract: Option<&FnContract>,
1379+
constness: Const,
13721380
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
13731381
) -> hir::BodyId {
13741382
self.lower_body(|this| {
1383+
if let Const::Yes(_) = constness {
1384+
this.is_in_const_context = true;
1385+
}
13751386
let params =
13761387
this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x)));
13771388

@@ -1389,16 +1400,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
13891400
decl: &FnDecl,
13901401
body: &Block,
13911402
contract: Option<&FnContract>,
1403+
constness: Const,
13921404
) -> hir::BodyId {
1393-
self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body))
1405+
self.lower_fn_body(decl, contract, constness, |this| this.lower_block_expr(body))
13941406
}
13951407

13961408
pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
13971409
self.lower_body(|this| {
13981410
(
13991411
&[],
14001412
match expr {
1401-
Some(expr) => this.lower_expr_mut(expr),
1413+
Some(expr) => {
1414+
this.is_in_const_context = true;
1415+
this.lower_expr_mut(expr)
1416+
}
14021417
None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
14031418
},
14041419
)
@@ -1417,12 +1432,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
14171432
body: Option<&Block>,
14181433
attrs: &'hir [hir::Attribute],
14191434
contract: Option<&FnContract>,
1435+
constness: Const,
14201436
) -> hir::BodyId {
14211437
let Some(body) = body else {
14221438
// Functions without a body are an error, except if this is an intrinsic. For those we
14231439
// create a fake body so that the entire rest of the compiler doesn't have to deal with
14241440
// this as a special case.
1425-
return self.lower_fn_body(decl, contract, |this| {
1441+
return self.lower_fn_body(decl, contract, constness, |this| {
14261442
if find_attr!(attrs, RustcIntrinsic) || this.tcx.is_sdylib_interface_build() {
14271443
let span = this.lower_span(span);
14281444
let empty_block = hir::Block {
@@ -1447,7 +1463,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14471463
};
14481464
let Some(coroutine_kind) = coroutine_kind else {
14491465
// Typical case: not a coroutine.
1450-
return self.lower_fn_body_block(decl, body, contract);
1466+
return self.lower_fn_body_block(decl, body, contract, constness);
14511467
};
14521468
// FIXME(contracts): Support contracts on async fn.
14531469
self.lower_body(|this| {

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ struct LoweringContext<'a, 'hir> {
129129
loop_scope: Option<HirId>,
130130
is_in_loop_condition: bool,
131131
is_in_dyn_type: bool,
132+
is_in_const_context: bool,
132133

133134
current_hir_id_owner: hir::OwnerId,
134135
item_local_id_counter: hir::ItemLocalId,
@@ -190,6 +191,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
190191
loop_scope: None,
191192
is_in_loop_condition: false,
192193
is_in_dyn_type: false,
194+
is_in_const_context: false,
193195
coroutine_kind: None,
194196
task_context: None,
195197
current_item: None,

compiler/rustc_data_structures/src/graph/linked_graph/mod.rs

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use std::fmt::Debug;
2424

2525
use rustc_index::bit_set::DenseBitSet;
26+
use rustc_index::{Idx, IndexSlice, IndexVec};
2627
use tracing::debug;
2728

2829
#[cfg(test)]
@@ -45,13 +46,13 @@ mod tests;
4546
/// and does not implement those traits, so it has its own implementations of a
4647
/// few basic graph algorithms.
4748
pub struct LinkedGraph<N, E> {
48-
nodes: Vec<Node<N>>,
49+
nodes: IndexVec<NodeIndex, Node<N>>,
4950
edges: Vec<Edge<E>>,
5051
}
5152

5253
pub struct Node<N> {
5354
first_edge: [EdgeIndex; 2], // see module comment
54-
pub data: N,
55+
pub data: Option<N>,
5556
}
5657

5758
#[derive(Debug)]
@@ -62,7 +63,7 @@ pub struct Edge<E> {
6263
pub data: E,
6364
}
6465

65-
#[derive(Copy, Clone, PartialEq, Debug)]
66+
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
6667
pub struct NodeIndex(pub usize);
6768

6869
#[derive(Copy, Clone, PartialEq, Debug)]
@@ -87,19 +88,29 @@ impl NodeIndex {
8788
}
8889
}
8990

91+
impl Idx for NodeIndex {
92+
fn new(idx: usize) -> NodeIndex {
93+
NodeIndex(idx)
94+
}
95+
96+
fn index(self) -> usize {
97+
self.0
98+
}
99+
}
100+
90101
impl<N: Debug, E: Debug> LinkedGraph<N, E> {
91102
pub fn new() -> Self {
92-
Self { nodes: Vec::new(), edges: Vec::new() }
103+
Self { nodes: IndexVec::new(), edges: Vec::new() }
93104
}
94105

95106
pub fn with_capacity(nodes: usize, edges: usize) -> Self {
96-
Self { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
107+
Self { nodes: IndexVec::with_capacity(nodes), edges: Vec::with_capacity(edges) }
97108
}
98109

99110
// # Simple accessors
100111

101112
#[inline]
102-
pub fn all_nodes(&self) -> &[Node<N>] {
113+
pub fn all_nodes(&self) -> &IndexSlice<NodeIndex, Node<N>> {
103114
&self.nodes
104115
}
105116

@@ -124,22 +135,34 @@ impl<N: Debug, E: Debug> LinkedGraph<N, E> {
124135
NodeIndex(self.nodes.len())
125136
}
126137

138+
fn ensure_node(&mut self, idx: NodeIndex) -> &mut Node<N> {
139+
self.nodes.ensure_contains_elem(idx, || Node {
140+
first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX],
141+
data: None,
142+
})
143+
}
144+
145+
pub fn add_node_with_idx(&mut self, idx: NodeIndex, data: N) {
146+
let old_data = self.ensure_node(idx).data.replace(data);
147+
debug_assert!(old_data.is_none());
148+
}
149+
127150
pub fn add_node(&mut self, data: N) -> NodeIndex {
128151
let idx = self.next_node_index();
129-
self.nodes.push(Node { first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX], data });
152+
self.add_node_with_idx(idx, data);
130153
idx
131154
}
132155

133156
pub fn mut_node_data(&mut self, idx: NodeIndex) -> &mut N {
134-
&mut self.nodes[idx.0].data
157+
self.nodes[idx].data.as_mut().unwrap()
135158
}
136159

137160
pub fn node_data(&self, idx: NodeIndex) -> &N {
138-
&self.nodes[idx.0].data
161+
self.nodes[idx].data.as_ref().unwrap()
139162
}
140163

141164
pub fn node(&self, idx: NodeIndex) -> &Node<N> {
142-
&self.nodes[idx.0]
165+
&self.nodes[idx]
143166
}
144167

145168
// # Edge construction and queries
@@ -154,16 +177,16 @@ impl<N: Debug, E: Debug> LinkedGraph<N, E> {
154177
let idx = self.next_edge_index();
155178

156179
// read current first of the list of edges from each node
157-
let source_first = self.nodes[source.0].first_edge[OUTGOING.repr];
158-
let target_first = self.nodes[target.0].first_edge[INCOMING.repr];
180+
let source_first = self.ensure_node(source).first_edge[OUTGOING.repr];
181+
let target_first = self.ensure_node(target).first_edge[INCOMING.repr];
159182

160183
// create the new edge, with the previous firsts from each node
161184
// as the next pointers
162185
self.edges.push(Edge { next_edge: [source_first, target_first], source, target, data });
163186

164187
// adjust the firsts for each node target be the next object.
165-
self.nodes[source.0].first_edge[OUTGOING.repr] = idx;
166-
self.nodes[target.0].first_edge[INCOMING.repr] = idx;
188+
self.nodes[source].first_edge[OUTGOING.repr] = idx;
189+
self.nodes[target].first_edge[INCOMING.repr] = idx;
167190

168191
idx
169192
}

compiler/rustc_data_structures/src/graph/linked_graph/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fn each_node() {
4040
let expected = ["A", "B", "C", "D", "E", "F"];
4141
graph.each_node(|idx, node| {
4242
assert_eq!(&expected[idx.0], graph.node_data(idx));
43-
assert_eq!(expected[idx.0], node.data);
43+
assert_eq!(expected[idx.0], node.data.unwrap());
4444
true
4545
});
4646
}

compiler/rustc_feature/src/unstable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ declare_features! (
431431
/// Allows defining and calling c-variadic functions in const contexts.
432432
(unstable, const_c_variadic, "1.95.0", Some(151787)),
433433
/// Allows `const || {}` closures in const contexts.
434-
(incomplete, const_closures, "1.68.0", Some(106003)),
434+
(unstable, const_closures, "1.68.0", Some(106003)),
435435
/// Allows using `[const] Destruct` bounds and calling drop impls in const contexts.
436436
(unstable, const_destruct, "1.85.0", Some(133214)),
437437
/// Allows `for _ in _` loops in const contexts.

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,9 @@ pub(super) fn const_conditions<'tcx>(
10691069
},
10701070
// N.B. Tuple ctors are unconditionally constant.
10711071
Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(),
1072+
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_), .. }) => {
1073+
(hir::Generics::empty(), None, tcx.is_conditionally_const(tcx.local_parent(def_id)))
1074+
}
10721075
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
10731076
};
10741077

compiler/rustc_middle/src/dep_graph/retained.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use rustc_data_structures::fx::FxHashMap;
22
use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, LinkedGraph, NodeIndex};
3-
use rustc_index::IndexVec;
43

54
use super::{DepNode, DepNodeIndex};
65

@@ -13,7 +12,6 @@ use super::{DepNode, DepNodeIndex};
1312
pub struct RetainedDepGraph {
1413
pub inner: LinkedGraph<DepNode, ()>,
1514
pub indices: FxHashMap<DepNode, NodeIndex>,
16-
pub dep_index_to_index: IndexVec<DepNodeIndex, Option<NodeIndex>>,
1715
}
1816

1917
impl RetainedDepGraph {
@@ -23,27 +21,22 @@ impl RetainedDepGraph {
2321

2422
let inner = LinkedGraph::with_capacity(node_count, edge_count);
2523
let indices = FxHashMap::default();
26-
let dep_index_to_index = IndexVec::new();
2724

28-
Self { inner, indices, dep_index_to_index }
25+
Self { inner, indices }
2926
}
3027

3128
pub fn push(&mut self, index: DepNodeIndex, node: DepNode, edges: &[DepNodeIndex]) {
32-
let source = self.inner.add_node(node);
33-
self.dep_index_to_index.insert(index, source);
29+
let source = NodeIndex(index.as_usize());
30+
self.inner.add_node_with_idx(source, node);
3431
self.indices.insert(node, source);
3532

3633
for &target in edges.iter() {
37-
// We may miss the edges that are pushed while the `DepGraphQuery` is being accessed.
38-
// Skip them to issues.
39-
if let Some(&Some(target)) = self.dep_index_to_index.get(target) {
40-
self.inner.add_edge(source, target, ());
41-
}
34+
self.inner.add_edge(source, NodeIndex(target.as_usize()), ());
4235
}
4336
}
4437

4538
pub fn nodes(&self) -> Vec<&DepNode> {
46-
self.inner.all_nodes().iter().map(|n| &n.data).collect()
39+
self.inner.all_nodes().iter().map(|n| n.data.as_ref().unwrap()).collect()
4740
}
4841

4942
pub fn edges(&self) -> Vec<(&DepNode, &DepNode)> {

0 commit comments

Comments
 (0)