Skip to content

Commit f7c0ba5

Browse files
committed
Enable effects for libcore
1 parent cb0c299 commit f7c0ba5

29 files changed

+271
-191
lines changed

compiler/rustc_codegen_ssa/src/common.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,11 @@ pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
123123
) -> (Bx::FnAbiOfResult, Bx::Value) {
124124
let tcx = bx.tcx();
125125
let def_id = tcx.require_lang_item(li, span);
126-
let instance = ty::Instance::mono(tcx, def_id);
126+
let instance = if li == LangItem::Panic {
127+
ty::Instance::new(def_id, tcx.mk_args(&[tcx.consts.true_.into()]))
128+
} else {
129+
ty::Instance::mono(tcx, def_id)
130+
};
127131
(bx.fn_abi_of_instance(instance, ty::List::empty()), bx.get_fn_addr(instance))
128132
}
129133

compiler/rustc_hir/src/lang_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ language_item_table! {
227227
// in the sense that a crate is not required to have it defined to use it, but a final product
228228
// is required to define it somewhere. Additionally, there are restrictions on crates that use
229229
// a weak lang item, but do not have it defined.
230-
Panic, sym::panic, panic_fn, Target::Fn, GenericRequirement::Exact(0);
230+
Panic, sym::panic, panic_fn, Target::Fn, GenericRequirement::Minimum(0);
231231
PanicNounwind, sym::panic_nounwind, panic_nounwind, Target::Fn, GenericRequirement::Exact(0);
232232
PanicFmt, sym::panic_fmt, panic_fmt, Target::Fn, GenericRequirement::None;
233233
PanicDisplay, sym::panic_display, panic_display, Target::Fn, GenericRequirement::None;

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

compiler/rustc_metadata/src/rmeta/encoder.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,7 @@ fn should_encode_span(def_kind: DefKind) -> bool {
846846
}
847847
}
848848

849-
fn should_encode_attrs(def_kind: DefKind) -> bool {
849+
fn should_encode_attrs(def_kind: DefKind, def_id: DefId, tcx: TyCtxt<'_>) -> bool {
850850
match def_kind {
851851
DefKind::Mod
852852
| DefKind::Struct
@@ -871,8 +871,9 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
871871
// https://github.com/model-checking/kani and is not a performance
872872
// or maintenance issue for us.
873873
DefKind::Closure => true,
874+
// encode the host param attr
875+
DefKind::ConstParam => tcx.has_attr(def_id, sym::rustc_host),
874876
DefKind::TyParam
875-
| DefKind::ConstParam
876877
| DefKind::Ctor(..)
877878
| DefKind::ExternCrate
878879
| DefKind::Use
@@ -1329,7 +1330,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13291330
let def_span = tcx.def_span(local_id);
13301331
record!(self.tables.def_span[def_id] <- def_span);
13311332
}
1332-
if should_encode_attrs(def_kind) {
1333+
if should_encode_attrs(def_kind, def_id, tcx) {
13331334
self.encode_attrs(local_id);
13341335
}
13351336
if should_encode_expn_that_defined(def_kind) {

compiler/rustc_monomorphize/src/collector.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -767,11 +767,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
767767
}
768768
}
769769
mir::TerminatorKind::Assert { ref msg, .. } => {
770-
let lang_item = match &**msg {
771-
mir::AssertKind::BoundsCheck { .. } => LangItem::PanicBoundsCheck,
772-
_ => LangItem::Panic,
770+
let (lang_item, has_host_effect) = match &**msg {
771+
mir::AssertKind::BoundsCheck { .. } => (LangItem::PanicBoundsCheck, false),
772+
_ => (LangItem::Panic, true),
773+
};
774+
let def_id = tcx.require_lang_item(lang_item, Some(source));
775+
let instance = if has_host_effect {
776+
Instance::new(def_id, tcx.mk_args(&[tcx.consts.true_.into()]))
777+
} else {
778+
Instance::mono(tcx, def_id)
773779
};
774-
let instance = Instance::mono(tcx, tcx.require_lang_item(lang_item, Some(source)));
775780
if should_codegen_locally(tcx, &instance) {
776781
self.output.push(create_fn_mono_item(tcx, instance, source));
777782
}

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@
185185
//
186186
// Language features:
187187
// tidy-alphabetical-start
188+
#![cfg_attr(not(bootstrap), feature(effects))]
188189
#![feature(abi_unadjusted)]
189190
#![feature(adt_const_params)]
190191
#![feature(allow_internal_unsafe)]

library/core/src/marker.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ marker_impls! {
966966
#[lang = "destruct"]
967967
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
968968
#[rustc_deny_explicit_impl(implement_via_object = false)]
969-
#[const_trait]
969+
// FIXME(effects) #[const_trait]
970970
pub trait Destruct {}
971971

972972
/// A marker for tuple types.

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"]
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
error[E0493]: destructor of `T` cannot be evaluated at compile-time
2-
--> $DIR/const-block-const-bound.rs:8:32
1+
error: ~const can only be applied to `#[const_trait]` traits
2+
--> $DIR/const-block-const-bound.rs:8:22
33
|
44
LL | const fn f<T: ~const Destruct>(x: T) {}
5-
| ^ - value is dropped here
6-
| |
7-
| the destructor for this type cannot be evaluated in constant functions
5+
| ^^^^^^^^
86

97
error: aborting due to previous error
108

11-
For more information about this error, try `rustc --explain E0493`.

tests/ui/consts/fn_trait_refs.stderr

+85-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,90 @@ 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:31
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:15:15
27+
|
28+
LL | T: ~const Fn<()> + ~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:22:34
39+
|
40+
LL | T: ~const FnMut<()> + ~const Destruct,
41+
| ^^^^^^^^
42+
43+
error: ~const can only be applied to `#[const_trait]` traits
44+
--> $DIR/fn_trait_refs.rs:22:15
45+
|
46+
LL | T: ~const FnMut<()> + ~const Destruct,
47+
| ^^^^^^^^^
48+
49+
error: ~const can only be applied to `#[const_trait]` traits
50+
--> $DIR/fn_trait_refs.rs:29:15
51+
|
52+
LL | T: ~const FnOnce<()>,
53+
| ^^^^^^^^^^
54+
55+
error: ~const can only be applied to `#[const_trait]` traits
56+
--> $DIR/fn_trait_refs.rs:29:15
57+
|
58+
LL | T: ~const FnOnce<()>,
59+
| ^^^^^^^^^^
60+
61+
error: ~const can only be applied to `#[const_trait]` traits
62+
--> $DIR/fn_trait_refs.rs:36:15
63+
|
64+
LL | T: ~const Fn<()> + ~const Destruct,
65+
| ^^^^^^
66+
67+
error: ~const can only be applied to `#[const_trait]` traits
68+
--> $DIR/fn_trait_refs.rs:36:31
69+
|
70+
LL | T: ~const Fn<()> + ~const Destruct,
71+
| ^^^^^^^^
72+
73+
error: ~const can only be applied to `#[const_trait]` traits
74+
--> $DIR/fn_trait_refs.rs:36:15
75+
|
76+
LL | T: ~const Fn<()> + ~const Destruct,
77+
| ^^^^^^
78+
79+
error: ~const can only be applied to `#[const_trait]` traits
80+
--> $DIR/fn_trait_refs.rs:50:15
81+
|
82+
LL | T: ~const FnMut<()> + ~const Destruct,
83+
| ^^^^^^^^^
84+
85+
error: ~const can only be applied to `#[const_trait]` traits
86+
--> $DIR/fn_trait_refs.rs:50:34
87+
|
88+
LL | T: ~const FnMut<()> + ~const Destruct,
89+
| ^^^^^^^^
90+
91+
error: ~const can only be applied to `#[const_trait]` traits
92+
--> $DIR/fn_trait_refs.rs:50:15
93+
|
94+
LL | T: ~const FnMut<()> + ~const Destruct,
95+
| ^^^^^^^^^
96+
97+
error: aborting due to 16 previous errors
1498

1599
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,14 @@
1-
error[E0015]: cannot call non-const closure in constant functions
2-
--> $DIR/normalize-tait-in-const.rs:26:5
1+
error: ~const can only be applied to `#[const_trait]` traits
2+
--> $DIR/normalize-tait-in-const.rs:25:42
33
|
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-
| ++++++++++++++++++++++++++++++++++++
4+
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
5+
| ^^^^^^^^^^^^^^^^^
126

13-
error[E0493]: destructor of `F` cannot be evaluated at compile-time
14-
--> $DIR/normalize-tait-in-const.rs:25:79
7+
error: ~const can only be applied to `#[const_trait]` traits
8+
--> $DIR/normalize-tait-in-const.rs:25:69
159
|
1610
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
11+
| ^^^^^^^^
2112

2213
error: aborting due to 2 previous errors
2314

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+

0 commit comments

Comments
 (0)