Skip to content

Commit 8759de0

Browse files
committed
Auto merge of #114776 - fee1-dead-contrib:enable-effects-in-libcore, r=oli-obk
Enable effects for libcore ~~r? `@oli-obk~~` forgot you are on vacation, oops
2 parents aace2df + ab168b6 commit 8759de0

19 files changed

+173
-133
lines changed

compiler/rustc_hir_typeck/src/expr.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
525525
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
526526
};
527527

528-
if let ty::FnDef(did, ..) = *ty.kind() {
528+
if let ty::FnDef(did, callee_args) = *ty.kind() {
529529
let fn_sig = ty.fn_sig(tcx);
530+
531+
// HACK: whenever we get a FnDef in a non-const context, enforce effects to get the
532+
// default `host = true` to avoid inference errors later.
533+
if tcx.hir().body_const_context(self.body_id).is_none() {
534+
self.enforce_context_effects(expr.hir_id, qpath.span(), did, callee_args);
535+
}
530536
if tcx.fn_sig(did).skip_binder().abi() == RustIntrinsic
531537
&& tcx.item_name(did) == sym::transmute
532538
{

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
273273
//
274274
// This check is here because there is currently no way to express a trait bound for `FnDef` types only.
275275
if is_const_eval_select && (1..=2).contains(&idx) {
276-
if let ty::FnDef(def_id, _) = checked_ty.kind() {
277-
if idx == 1 && !self.tcx.is_const_fn_raw(*def_id) {
278-
self.tcx
279-
.sess
280-
.emit_err(errors::ConstSelectMustBeConst { span: provided_arg.span });
276+
if let ty::FnDef(def_id, args) = *checked_ty.kind() {
277+
if idx == 1 {
278+
if !self.tcx.is_const_fn_raw(def_id) {
279+
self.tcx.sess.emit_err(errors::ConstSelectMustBeConst {
280+
span: provided_arg.span,
281+
});
282+
} else {
283+
self.enforce_context_effects(
284+
provided_arg.hir_id,
285+
provided_arg.span,
286+
def_id,
287+
args,
288+
)
289+
}
281290
}
282291
} else {
283292
self.tcx.sess.emit_err(errors::ConstSelectMustBeFn {

compiler/rustc_passes/src/lang_items.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use rustc_hir::lang_items::{extract, GenericRequirement};
2020
use rustc_hir::{LangItem, LanguageItems, Target};
2121
use rustc_middle::ty::TyCtxt;
2222
use rustc_session::cstore::ExternCrate;
23-
use rustc_span::{symbol::kw::Empty, Span};
23+
use rustc_span::symbol::kw::Empty;
24+
use rustc_span::{sym, Span};
2425

2526
use rustc_middle::query::Providers;
2627

@@ -157,7 +158,14 @@ impl<'tcx> LanguageItemCollector<'tcx> {
157158
self.tcx.hir().get_by_def_id(item_def_id)
158159
{
159160
let (actual_num, generics_span) = match kind.generics() {
160-
Some(generics) => (generics.params.len(), generics.span),
161+
Some(generics) => (
162+
generics
163+
.params
164+
.iter()
165+
.filter(|p| !self.tcx.has_attr(p.def_id, sym::rustc_host))
166+
.count(),
167+
generics.span,
168+
),
161169
None => (0, *item_span),
162170
};
163171

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@
195195
//
196196
// Language features:
197197
// tidy-alphabetical-start
198+
#![cfg_attr(not(bootstrap), feature(effects))]
198199
#![feature(abi_unadjusted)]
199200
#![feature(adt_const_params)]
200201
#![feature(allow_internal_unsafe)]

library/core/src/ops/drop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@
202202
/// [nomicon]: ../../nomicon/phantom-data.html#an-exception-the-special-case-of-the-standard-library-and-its-unstable-may_dangle
203203
#[lang = "drop"]
204204
#[stable(feature = "rust1", since = "1.0.0")]
205-
#[const_trait]
205+
// FIXME(effects) #[const_trait]
206206
pub trait Drop {
207207
/// Executes the destructor for this type.
208208
///

library/core/src/ops/function.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ use crate::marker::Tuple;
7272
)]
7373
#[fundamental] // so that regex can rely that `&str: !FnMut`
7474
#[must_use = "closures are lazy and do nothing unless called"]
75-
#[const_trait]
75+
// FIXME(effects) #[const_trait]
7676
pub trait Fn<Args: Tuple>: FnMut<Args> {
7777
/// Performs the call operation.
7878
#[unstable(feature = "fn_traits", issue = "29625")]
@@ -159,7 +159,7 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
159159
)]
160160
#[fundamental] // so that regex can rely that `&str: !FnMut`
161161
#[must_use = "closures are lazy and do nothing unless called"]
162-
#[const_trait]
162+
// FIXME(effects) #[const_trait]
163163
pub trait FnMut<Args: Tuple>: FnOnce<Args> {
164164
/// Performs the call operation.
165165
#[unstable(feature = "fn_traits", issue = "29625")]
@@ -238,7 +238,7 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
238238
)]
239239
#[fundamental] // so that regex can rely that `&str: !FnMut`
240240
#[must_use = "closures are lazy and do nothing unless called"]
241-
#[const_trait]
241+
// FIXME(effects) #[const_trait]
242242
pub trait FnOnce<Args: Tuple> {
243243
/// The returned type after the call operator is used.
244244
#[lang = "fn_once_output"]

src/librustdoc/clean/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@ fn clean_ty_generics<'tcx>(
793793
}
794794
Some(clean_generic_param_def(param, cx))
795795
}
796+
ty::GenericParamDefKind::Const { is_host_effect: true, .. } => None,
796797
ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)),
797798
})
798799
.collect::<ThinVec<GenericParamDef>>();

src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ fn path_segment_certainty(
207207
// Checking `res_generics_def_id(..)` before calling `generics_of` avoids an ICE.
208208
if cx.tcx.res_generics_def_id(path_segment.res).is_some() {
209209
let generics = cx.tcx.generics_of(def_id);
210-
let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && generics.params.is_empty()
210+
let count = generics.params.len() - generics.host_effect_index.is_some() as usize;
211+
let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && count == 0
211212
{
212213
Certainty::Certain(None)
213214
} else {
@@ -299,7 +300,7 @@ fn type_is_inferrable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> b
299300

300301
// Check that all type parameters appear in the functions input types.
301302
(0..(generics.parent_count + generics.params.len()) as u32).all(|index| {
302-
fn_sig
303+
Some(index as usize) == generics.host_effect_index || fn_sig
303304
.inputs()
304305
.iter()
305306
.any(|input_ty| contains_param(*input_ty.skip_binder(), index))

tests/rustdoc/rfc-2632-const-trait-impl.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// To future blessers: make sure that `const_trait_impl` is
66
// stabilized when changing `@!has` to `@has`, and please do
77
// not remove this test.
8+
//
9+
// FIXME(effects) add `const_trait` to `Fn` so we use `~const`
810
#![feature(const_trait_impl)]
911
#![crate_name = "foo"]
1012

@@ -22,9 +24,9 @@ pub trait Tr<T> {
2224
// @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn'
2325
// @!has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
2426
// @has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn'
25-
fn a<A: ~const Fn() + ~const Destruct>()
27+
fn a<A: /* ~const */ Fn() + ~const Destruct>()
2628
where
27-
Option<A>: ~const Fn() + ~const Destruct,
29+
Option<A>: /* ~const */ Fn() + ~const Destruct,
2830
{
2931
}
3032
}
@@ -34,13 +36,13 @@ pub trait Tr<T> {
3436
// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/a[@class="trait"]' 'Fn'
3537
// @!has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where"]' '~const'
3638
// @has - '//section[@id="impl-Tr%3CT%3E-for-T"]/h3[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn'
37-
impl<T: ~const Fn() + ~const Destruct> const Tr<T> for T
39+
impl<T: /* ~const */ Fn() + ~const Destruct> const Tr<T> for T
3840
where
39-
Option<T>: ~const Fn() + ~const Destruct,
41+
Option<T>: /* ~const */ Fn() + ~const Destruct,
4042
{
41-
fn a<A: ~const Fn() + ~const Destruct>()
43+
fn a<A: /* ~const */ Fn() + ~const Destruct>()
4244
where
43-
Option<A>: ~const Fn() + ~const Destruct,
45+
Option<A>: /* ~const */ Fn() + ~const Destruct,
4446
{
4547
}
4648
}
@@ -49,9 +51,9 @@ where
4951
// @has - '//pre[@class="rust item-decl"]/code/a[@class="trait"]' 'Fn'
5052
// @!has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' '~const'
5153
// @has - '//pre[@class="rust item-decl"]/code/span[@class="where fmt-newline"]' ': Fn'
52-
pub const fn foo<F: ~const Fn() + ~const Destruct>()
54+
pub const fn foo<F: /* ~const */ Fn() + ~const Destruct>()
5355
where
54-
Option<F>: ~const Fn() + ~const Destruct,
56+
Option<F>: /* ~const */ Fn() + ~const Destruct,
5557
{
5658
F::a()
5759
}
@@ -61,9 +63,9 @@ impl<T> S<T> {
6163
// @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Fn'
6264
// @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const'
6365
// @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Fn'
64-
pub const fn foo<B, C: ~const Fn() + ~const Destruct>()
66+
pub const fn foo<B, C: /* ~const */ Fn() + ~const Destruct>()
6567
where
66-
B: ~const Fn() + ~const Destruct,
68+
B: /* ~const */ Fn() + ~const Destruct,
6769
{
6870
B::a()
6971
}

tests/ui/consts/fn_trait_refs.stderr

+61-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,66 @@ error[E0635]: unknown feature `const_cmp`
1010
LL | #![feature(const_cmp)]
1111
| ^^^^^^^^^
1212

13-
error: aborting due to 2 previous errors
13+
error: ~const can only be applied to `#[const_trait]` traits
14+
--> $DIR/fn_trait_refs.rs:15:15
15+
|
16+
LL | T: ~const Fn<()> + ~const Destruct,
17+
| ^^^^^^
18+
19+
error: ~const can only be applied to `#[const_trait]` traits
20+
--> $DIR/fn_trait_refs.rs:15:15
21+
|
22+
LL | T: ~const Fn<()> + ~const Destruct,
23+
| ^^^^^^
24+
25+
error: ~const can only be applied to `#[const_trait]` traits
26+
--> $DIR/fn_trait_refs.rs:22:15
27+
|
28+
LL | T: ~const FnMut<()> + ~const Destruct,
29+
| ^^^^^^^^^
30+
31+
error: ~const can only be applied to `#[const_trait]` traits
32+
--> $DIR/fn_trait_refs.rs:22:15
33+
|
34+
LL | T: ~const FnMut<()> + ~const Destruct,
35+
| ^^^^^^^^^
36+
37+
error: ~const can only be applied to `#[const_trait]` traits
38+
--> $DIR/fn_trait_refs.rs:29:15
39+
|
40+
LL | T: ~const FnOnce<()>,
41+
| ^^^^^^^^^^
42+
43+
error: ~const can only be applied to `#[const_trait]` traits
44+
--> $DIR/fn_trait_refs.rs:29:15
45+
|
46+
LL | T: ~const FnOnce<()>,
47+
| ^^^^^^^^^^
48+
49+
error: ~const can only be applied to `#[const_trait]` traits
50+
--> $DIR/fn_trait_refs.rs:36:15
51+
|
52+
LL | T: ~const Fn<()> + ~const Destruct,
53+
| ^^^^^^
54+
55+
error: ~const can only be applied to `#[const_trait]` traits
56+
--> $DIR/fn_trait_refs.rs:36:15
57+
|
58+
LL | T: ~const Fn<()> + ~const Destruct,
59+
| ^^^^^^
60+
61+
error: ~const can only be applied to `#[const_trait]` traits
62+
--> $DIR/fn_trait_refs.rs:50:15
63+
|
64+
LL | T: ~const FnMut<()> + ~const Destruct,
65+
| ^^^^^^^^^
66+
67+
error: ~const can only be applied to `#[const_trait]` traits
68+
--> $DIR/fn_trait_refs.rs:50:15
69+
|
70+
LL | T: ~const FnMut<()> + ~const Destruct,
71+
| ^^^^^^^^^
72+
73+
error: aborting due to 12 previous errors
1474

1575
For more information about this error, try `rustc --explain E0635`.

tests/ui/consts/unstable-const-fn-in-libcore.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// known-bug: #110395
2+
// FIXME check-pass
13
// This is a non-regression test for const-qualification of unstable items in libcore
24
// as explained in issue #67053.
35
// const-qualification could miss some `const fn`s if they were unstable and the feature
@@ -15,12 +17,12 @@ impl<T> Opt<T> {
1517
#[rustc_const_unstable(feature = "foo", issue = "none")]
1618
#[stable(feature = "rust1", since = "1.0.0")]
1719
const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
18-
//~^ ERROR destructor of
19-
//~| ERROR destructor of
20+
//FIXME ~^ ERROR destructor of
21+
//FIXME ~| ERROR destructor of
2022
match self {
2123
Opt::Some(t) => t,
2224
Opt::None => f(),
23-
//~^ ERROR cannot call
25+
//FIXME ~^ ERROR cannot call
2426
}
2527
}
2628
}
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,8 @@
1-
error[E0015]: cannot call non-const closure in constant functions
2-
--> $DIR/unstable-const-fn-in-libcore.rs:22:26
3-
|
4-
LL | Opt::None => f(),
5-
| ^^^
6-
|
7-
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
8-
help: consider further restricting this bound
9-
|
10-
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T + ~const std::ops::FnOnce<()>>(self, f: F) -> T {
11-
| +++++++++++++++++++++++++++++
12-
13-
error[E0493]: destructor of `F` cannot be evaluated at compile-time
14-
--> $DIR/unstable-const-fn-in-libcore.rs:17:60
15-
|
16-
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
17-
| ^ the destructor for this type cannot be evaluated in constant functions
18-
...
19-
LL | }
20-
| - value is dropped here
21-
22-
error[E0493]: destructor of `Opt<T>` cannot be evaluated at compile-time
23-
--> $DIR/unstable-const-fn-in-libcore.rs:17:54
1+
error: ~const can only be applied to `#[const_trait]` traits
2+
--> $DIR/unstable-const-fn-in-libcore.rs:19:39
243
|
254
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
26-
| ^^^^ the destructor for this type cannot be evaluated in constant functions
27-
...
28-
LL | }
29-
| - value is dropped here
5+
| ^^^^^^^^^^^^^
306

31-
error: aborting due to 3 previous errors
7+
error: aborting due to previous error
328

33-
Some errors have detailed explanations: E0015, E0493.
34-
For more information about an error, try `rustc --explain E0015`.
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,8 @@
1-
error[E0015]: cannot call non-const closure in constant functions
2-
--> $DIR/normalize-tait-in-const.rs:26:5
3-
|
4-
LL | fun(filter_positive());
5-
| ^^^^^^^^^^^^^^^^^^^^^^
6-
|
7-
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
8-
help: consider further restricting this bound
9-
|
10-
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct + ~const std::ops::Fn<(&Alias<'_>,)>>(fun: F) {
11-
| ++++++++++++++++++++++++++++++++++++
12-
13-
error[E0493]: destructor of `F` cannot be evaluated at compile-time
14-
--> $DIR/normalize-tait-in-const.rs:25:79
1+
error: ~const can only be applied to `#[const_trait]` traits
2+
--> $DIR/normalize-tait-in-const.rs:25:42
153
|
164
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
17-
| ^^^ the destructor for this type cannot be evaluated in constant functions
18-
LL | fun(filter_positive());
19-
LL | }
20-
| - value is dropped here
5+
| ^^^^^^^^^^^^^^^^^
216

22-
error: aborting due to 2 previous errors
7+
error: aborting due to previous error
238

24-
Some errors have detailed explanations: E0015, E0493.
25-
For more information about an error, try `rustc --explain E0015`.

tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-parse-not-item.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// check-pass
1+
// known-bug: #110395
2+
// FIXME check-pass
23

34
#![feature(const_trait_impl, const_closures)]
45
#![allow(incomplete_features)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: ~const can only be applied to `#[const_trait]` traits
2+
--> $DIR/const-closure-parse-not-item.rs:7:32
3+
|
4+
LL | const fn test() -> impl ~const Fn() {
5+
| ^^^^
6+
7+
error: aborting due to previous error
8+
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
error[E0015]: cannot call non-const closure in constant functions
2-
--> $DIR/const-closure-trait-method-fail.rs:15:5
1+
error: ~const can only be applied to `#[const_trait]` traits
2+
--> $DIR/const-closure-trait-method-fail.rs:14:39
33
|
4-
LL | x(())
5-
| ^^^^^
6-
|
7-
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
8-
help: consider further restricting this bound
9-
|
10-
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32 + ~const std::ops::FnOnce<((),)>>(x: T) -> i32 {
11-
| ++++++++++++++++++++++++++++++++
4+
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
5+
| ^^^^^^^^^^^^^^^^^
126

137
error: aborting due to previous error
148

15-
For more information about this error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)