Skip to content

Commit 2f43fe4

Browse files
committed
Auto merge of #155863 - jhpratt:rollup-6wWyVPM, r=jhpratt
Rollup of 3 pull requests Successful merges: - #155772 (Check closure's constness validity in the constness query) - #155833 (CI: rfl: move job forward to Linux v7.0) - #155839 (Remove unnecessary requires_lto: false for eBPF)
2 parents 4933094 + 88cc005 commit 2f43fe4

13 files changed

Lines changed: 57 additions & 50 deletions

File tree

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10521052
binder: &ClosureBinder,
10531053
capture_clause: CaptureBy,
10541054
closure_id: NodeId,
1055-
mut constness: Const,
1055+
constness: Const,
10561056
movability: Movability,
10571057
decl: &FnDecl,
10581058
body: &Expr,
@@ -1062,18 +1062,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
10621062
let closure_def_id = self.local_def_id(closure_id);
10631063
let (binder_clause, generic_params) = self.lower_closure_binder(binder);
10641064

1065-
if let Const::Yes(span) = constness {
1066-
if !self.is_in_const_context {
1067-
self.dcx().span_err(span, "cannot use `const` closures outside of const contexts");
1068-
constness = Const::No;
1069-
}
1070-
}
1071-
10721065
let (body_id, closure_kind) = self.with_new_scopes(fn_decl_span, move |this| {
10731066
let mut coroutine_kind = find_attr!(attrs, Coroutine(_) => hir::CoroutineKind::Coroutine(Movability::Movable));
10741067

10751068
// FIXME(contracts): Support contracts on closures?
1076-
let body_id = this.lower_fn_body(decl, None, constness, |this| {
1069+
let body_id = this.lower_fn_body(decl, None, |this| {
10771070
this.coroutine_kind = coroutine_kind;
10781071
let e = this.lower_expr_mut(body);
10791072
coroutine_kind = this.coroutine_kind;

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::mem;
2-
31
use rustc_abi::ExternAbi;
42
use rustc_ast::visit::AssocCtxt;
53
use rustc_ast::*;
@@ -378,7 +376,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
378376
body.as_deref(),
379377
attrs,
380378
contract.as_deref(),
381-
header.constness,
382379
);
383380

384381
let itctx = ImplTraitContext::Universal;
@@ -1068,7 +1065,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
10681065
Some(body),
10691066
attrs,
10701067
contract.as_deref(),
1071-
sig.header.constness,
10721068
);
10731069
let (generics, sig) = self.lower_method_sig(
10741070
generics,
@@ -1262,7 +1258,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
12621258
body.as_deref(),
12631259
attrs,
12641260
contract.as_deref(),
1265-
sig.header.constness,
12661261
);
12671262
let (generics, sig) = self.lower_method_sig(
12681263
generics,
@@ -1391,13 +1386,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
13911386
f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
13921387
) -> hir::BodyId {
13931388
let prev_coroutine_kind = self.coroutine_kind.take();
1394-
let prev_is_in_const_context = mem::take(&mut self.is_in_const_context);
13951389
let task_context = self.task_context.take();
13961390
let (parameters, result) = f(self);
13971391
let body_id = self.record_body(parameters, result);
13981392
self.task_context = task_context;
13991393
self.coroutine_kind = prev_coroutine_kind;
1400-
self.is_in_const_context = prev_is_in_const_context;
14011394
body_id
14021395
}
14031396

@@ -1416,13 +1409,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
14161409
&mut self,
14171410
decl: &FnDecl,
14181411
contract: Option<&FnContract>,
1419-
constness: Const,
14201412
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
14211413
) -> hir::BodyId {
14221414
self.lower_body(|this| {
1423-
if let Const::Yes(_) = constness {
1424-
this.is_in_const_context = true;
1425-
}
14261415
let params =
14271416
this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x)));
14281417

@@ -1440,20 +1429,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
14401429
decl: &FnDecl,
14411430
body: &Block,
14421431
contract: Option<&FnContract>,
1443-
constness: Const,
14441432
) -> hir::BodyId {
1445-
self.lower_fn_body(decl, contract, constness, |this| this.lower_block_expr(body))
1433+
self.lower_fn_body(decl, contract, |this| this.lower_block_expr(body))
14461434
}
14471435

14481436
pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
14491437
self.lower_body(|this| {
14501438
(
14511439
&[],
14521440
match expr {
1453-
Some(expr) => {
1454-
this.is_in_const_context = true;
1455-
this.lower_expr_mut(expr)
1456-
}
1441+
Some(expr) => this.lower_expr_mut(expr),
14571442
None => this.expr_err(span, this.dcx().span_delayed_bug(span, "no block")),
14581443
},
14591444
)
@@ -1472,13 +1457,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
14721457
body: Option<&Block>,
14731458
attrs: &'hir [hir::Attribute],
14741459
contract: Option<&FnContract>,
1475-
constness: Const,
14761460
) -> hir::BodyId {
14771461
let Some(body) = body else {
14781462
// Functions without a body are an error, except if this is an intrinsic. For those we
14791463
// create a fake body so that the entire rest of the compiler doesn't have to deal with
14801464
// this as a special case.
1481-
return self.lower_fn_body(decl, contract, constness, |this| {
1465+
return self.lower_fn_body(decl, contract, |this| {
14821466
if find_attr!(attrs, RustcIntrinsic) || this.tcx.is_sdylib_interface_build() {
14831467
let span = this.lower_span(span);
14841468
let empty_block = hir::Block {
@@ -1503,7 +1487,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
15031487
};
15041488
let Some(coroutine_kind) = coroutine_kind else {
15051489
// Typical case: not a coroutine.
1506-
return self.lower_fn_body_block(decl, body, contract, constness);
1490+
return self.lower_fn_body_block(decl, body, contract);
15071491
};
15081492
// FIXME(contracts): Support contracts on async fn.
15091493
self.lower_body(|this| {

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ struct LoweringContext<'a, 'hir> {
124124
loop_scope: Option<HirId>,
125125
is_in_loop_condition: bool,
126126
is_in_dyn_type: bool,
127-
is_in_const_context: bool,
128127

129128
current_hir_id_owner: hir::OwnerId,
130129
item_local_id_counter: hir::ItemLocalId,
@@ -193,7 +192,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
193192
loop_scope: None,
194193
is_in_loop_condition: false,
195194
is_in_dyn_type: false,
196-
is_in_const_context: false,
197195
coroutine_kind: None,
198196
task_context: None,
199197
current_item: None,

compiler/rustc_const_eval/src/const_eval/fn_queries.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,13 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Constness {
1616
// Foreign functions cannot be evaluated at compile-time.
1717
Constness::NotConst
1818
}
19-
Node::Expr(e) if let ExprKind::Closure(c) = e.kind => c.constness,
19+
Node::Expr(e) if let ExprKind::Closure(c) = e.kind => {
20+
if let Constness::Const = c.constness && tcx.hir_body_const_context(tcx.local_parent(def_id)).is_none() {
21+
tcx.dcx().span_err(tcx.def_span(def_id), "cannot use `const` closures outside of const contexts");
22+
return Constness::NotConst;
23+
}
24+
c.constness
25+
},
2026
// FIXME(fee1-dead): extract this one out and rename this query to `fn_constness` so we don't need `is_const_fn` anymore.
2127
Node::Item(i) if let ItemKind::Impl(impl_) = i.kind => impl_.constness,
2228
Node::Item(Item { kind: ItemKind::Fn { sig, .. }, .. }) => sig.header.constness,

compiler/rustc_middle/src/hir/map.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -319,17 +319,7 @@ impl<'tcx> TyCtxt<'tcx> {
319319
BodyOwnerKind::Fn if self.is_constructor(def_id) => return None,
320320
// Const closures use their parent's const context
321321
BodyOwnerKind::Closure if self.is_const_fn(def_id) => {
322-
return Some(
323-
self.hir_body_const_context(self.local_parent(local_def_id)).unwrap_or_else(
324-
|| {
325-
assert!(
326-
self.dcx().has_errors().is_some(),
327-
"`const` closure with no enclosing const context",
328-
);
329-
ConstContext::ConstFn
330-
},
331-
),
332-
);
322+
return self.hir_body_const_context(self.local_parent(local_def_id));
333323
}
334324
BodyOwnerKind::Fn if self.is_const_fn(def_id) => ConstContext::ConstFn,
335325
BodyOwnerKind::Fn | BodyOwnerKind::Closure | BodyOwnerKind::GlobalAsm => return None,

compiler/rustc_target/src/spec/base/bpf.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ pub(crate) fn opts(endian: Endian) -> TargetOptions {
1818
// BPF_PROG_LOAD and not all BPF libraries do that yet
1919
merge_functions: MergeFunctions::Disabled,
2020
obj_is_bitcode: true,
21-
requires_lto: false,
2221
singlethread: true,
2322
// When targeting the `v3` cpu in llvm, 32-bit atomics are also supported.
2423
// But making this value change based on the target cpu can be mostly confusing

src/ci/docker/scripts/rfl-build.sh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
set -euo pipefail
44

5-
# https://github.com/rust-lang/rust/pull/151534
6-
# https://github.com/rust-lang/rust/pull/149389
7-
LINUX_VERSION=167ea5357eb7c3a39200627a36dfbfe249576192
5+
LINUX_VERSION=v7.0
86

97
# Build rustc, rustdoc, cargo, clippy-driver and rustfmt
108
../x.py build --stage 2 library rustdoc clippy rustfmt
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//@ check-pass
2+
3+
#![feature(const_closures, const_destruct, const_trait_impl)]
4+
5+
use std::marker::Destruct;
6+
use std::num::NonZero;
7+
8+
const trait T {
9+
fn a(&mut self, f: impl [const] Fn() + [const] Destruct);
10+
fn b(&mut self);
11+
}
12+
13+
struct S;
14+
15+
impl const T for S {
16+
fn a(&mut self, f: impl [const] Fn() + [const] Destruct) {
17+
f()
18+
}
19+
20+
fn b(&mut self) {
21+
self.a(const || {});
22+
}
23+
}
24+
25+
fn main() {}

tests/ui/traits/const-traits/const-closure-in-non-const-trait-impl-method.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ impl<T: Foo> Foo for &mut T {
1111
const fn test() -> impl [const] Fn() {
1212
//~^ ERROR functions in trait impls cannot be declared const
1313
const move || {}
14+
//~^ ERROR: cannot use `const` closures outside of const contexts
1415
}
1516
}
1617

tests/ui/traits/const-traits/const-closure-in-non-const-trait-impl-method.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ help: ... and declare the impl to be const instead
1414
LL | impl<T: Foo> const Foo for &mut T {
1515
| +++++
1616

17-
error: aborting due to 1 previous error
17+
error: cannot use `const` closures outside of const contexts
18+
--> $DIR/const-closure-in-non-const-trait-impl-method.rs:13:9
19+
|
20+
LL | const move || {}
21+
| ^^^^^^^^^^^^^
22+
23+
error: aborting due to 2 previous errors
1824

1925
For more information about this error, try `rustc --explain E0379`.

0 commit comments

Comments
 (0)