Skip to content

Commit f2f6723

Browse files
committed
Deny calls to non-#[const_trait] methods in MIR constck
1 parent 54761cb commit f2f6723

File tree

75 files changed

+438
-324
lines changed

Some content is hidden

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

75 files changed

+438
-324
lines changed

compiler/rustc_const_eval/src/check_consts/check.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -616,14 +616,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
616616

617617
let mut is_trait = false;
618618
// Attempting to call a trait method?
619-
if tcx.trait_of_item(callee).is_some() {
619+
if let Some(trait_did) = tcx.trait_of_item(callee) {
620620
trace!("attempting to call a trait method");
621+
622+
let trait_is_const = tcx.is_const_trait(trait_did);
621623
// trait method calls are only permitted when `effects` is enabled.
622-
// we don't error, since that is handled by typeck. We try to resolve
623-
// the trait into the concrete method, and uses that for const stability
624-
// checks.
624+
// typeck ensures the conditions for calling a const trait method are met,
625+
// so we only error if the trait isn't const. We try to resolve the trait
626+
// into the concrete method, and uses that for const stability checks.
625627
// FIXME(effects) we might consider moving const stability checks to typeck as well.
626-
if tcx.features().effects() {
628+
if tcx.features().effects() && trait_is_const {
627629
// This skips the check below that ensures we only call `const fn`.
628630
is_trait = true;
629631

@@ -638,17 +640,24 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
638640
callee = def;
639641
}
640642
} else {
643+
// if the trait is const but the user has not enabled the feature(s),
644+
// suggest them.
645+
let feature = if trait_is_const {
646+
Some(if tcx.features().const_trait_impl() {
647+
sym::effects
648+
} else {
649+
sym::const_trait_impl
650+
})
651+
} else {
652+
None
653+
};
641654
self.check_op(ops::FnCallNonConst {
642655
caller,
643656
callee,
644657
args: fn_args,
645658
span: *fn_span,
646659
call_source,
647-
feature: Some(if tcx.features().const_trait_impl() {
648-
sym::effects
649-
} else {
650-
sym::const_trait_impl
651-
}),
660+
feature,
652661
});
653662
// If we allowed this, we're in miri-unleashed mode, so we might
654663
// as well skip the remaining checks.

tests/ui/const-generics/generic_const_exprs/unify-op-with-fn-call.stderr

+21-9
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ LL + #[derive(ConstParamTy)]
2727
LL | struct Foo(u8);
2828
|
2929

30-
error[E0284]: type annotations needed: cannot normalize `foo<N>::{constant#0}`
31-
--> $DIR/unify-op-with-fn-call.rs:20:25
30+
error[E0015]: cannot call non-const operator in constants
31+
--> $DIR/unify-op-with-fn-call.rs:20:39
3232
|
3333
LL | fn foo<const N: Foo>(a: Evaluatable<{ N + N }>) {
34-
| ^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo<N>::{constant#0}`
34+
| ^^^^^
35+
|
36+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
3537

3638
error[E0741]: `Foo` must implement `ConstParamTy` to be used as the type of a const generic parameter
3739
--> $DIR/unify-op-with-fn-call.rs:20:17
@@ -63,19 +65,29 @@ error[E0284]: type annotations needed: cannot normalize `foo2<N>::{constant#0}`
6365
LL | fn foo2<const N: usize>(a: Evaluatable2<{ N + N }>) {
6466
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2<N>::{constant#0}`
6567

66-
error[E0284]: type annotations needed: cannot normalize `foo<N>::{constant#0}`
67-
--> $DIR/unify-op-with-fn-call.rs:21:11
68+
error[E0015]: cannot call non-const fn `<Foo as Add>::add` in constants
69+
--> $DIR/unify-op-with-fn-call.rs:21:13
6870
|
6971
LL | bar::<{ std::ops::Add::add(N, N) }>();
70-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo<N>::{constant#0}`
72+
| ^^^^^^^^^^^^^^^^^^^^^^^^
73+
|
74+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
75+
76+
error[E0015]: cannot call non-const fn `<usize as Add>::add` in constants
77+
--> $DIR/unify-op-with-fn-call.rs:30:14
78+
|
79+
LL | bar2::<{ std::ops::Add::add(N, N) }>();
80+
| ^^^^^^^^^^^^^^^^^^^^^^^^
81+
|
82+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
7183

7284
error[E0284]: type annotations needed: cannot normalize `foo2<N>::{constant#0}`
7385
--> $DIR/unify-op-with-fn-call.rs:30:12
7486
|
7587
LL | bar2::<{ std::ops::Add::add(N, N) }>();
7688
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo2<N>::{constant#0}`
7789

78-
error: aborting due to 9 previous errors
90+
error: aborting due to 10 previous errors
7991

80-
Some errors have detailed explanations: E0284, E0741.
81-
For more information about an error, try `rustc --explain E0284`.
92+
Some errors have detailed explanations: E0015, E0284, E0741.
93+
For more information about an error, try `rustc --explain E0015`.

tests/ui/const-generics/issue-93647.stderr

-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ LL | (||1usize)()
66
|
77
= note: closures need an RFC before allowed to be called in constants
88
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
9-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
10-
|
11-
LL + #![feature(const_trait_impl)]
12-
|
139

1410
error: aborting due to 1 previous error
1511

tests/ui/const-generics/issues/issue-90318.stderr

-8
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
2929
note: impl defined here, but it is not `const`
3030
--> $SRC_DIR/core/src/any.rs:LL:COL
3131
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
32-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
33-
|
34-
LL + #![feature(const_trait_impl)]
35-
|
3632

3733
error[E0015]: cannot call non-const operator in constants
3834
--> $DIR/issue-90318.rs:22:10
@@ -43,10 +39,6 @@ LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
4339
note: impl defined here, but it is not `const`
4440
--> $SRC_DIR/core/src/any.rs:LL:COL
4541
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
46-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
47-
|
48-
LL + #![feature(const_trait_impl)]
49-
|
5042

5143
error: aborting due to 4 previous errors
5244

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
//@ aux-build:closure-in-foreign-crate.rs
1+
// FIXME(effects) aux-build:closure-in-foreign-crate.rs
22
//@ build-pass
33

4-
extern crate closure_in_foreign_crate;
4+
// FIXME(effects) extern crate closure_in_foreign_crate;
55

6-
const _: () = closure_in_foreign_crate::test();
6+
// FIXME(effects) const _: () = closure_in_foreign_crate::test();
77

88
fn main() {}

tests/ui/consts/const-fn-error.stderr

-8
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ LL | for i in 0..x {
2222
note: impl defined here, but it is not `const`
2323
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
2424
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
25-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
26-
|
27-
LL + #![feature(const_trait_impl)]
28-
|
2925

3026
error[E0015]: cannot call non-const fn `<std::ops::Range<usize> as Iterator>::next` in constant functions
3127
--> $DIR/const-fn-error.rs:5:14
@@ -34,10 +30,6 @@ LL | for i in 0..x {
3430
| ^^^^
3531
|
3632
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
37-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
38-
|
39-
LL + #![feature(const_trait_impl)]
40-
|
4133

4234
error: aborting due to 3 previous errors
4335

tests/ui/consts/const-for-feature-gate.stderr

-8
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ LL | for _ in 0..5 {}
1717
note: impl defined here, but it is not `const`
1818
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
1919
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
20-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
21-
|
22-
LL + #![feature(const_trait_impl)]
23-
|
2420

2521
error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
2622
--> $DIR/const-for-feature-gate.rs:4:14
@@ -29,10 +25,6 @@ LL | for _ in 0..5 {}
2925
| ^^^^
3026
|
3127
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
32-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
33-
|
34-
LL + #![feature(const_trait_impl)]
35-
|
3628

3729
error: aborting due to 3 previous errors
3830

tests/ui/consts/const-for.stderr

-8
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ LL | for _ in 0..5 {}
77
note: impl defined here, but it is not `const`
88
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
99
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
10-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
11-
|
12-
LL + #![feature(const_trait_impl)]
13-
|
1410

1511
error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
1612
--> $DIR/const-for.rs:4:14
@@ -19,10 +15,6 @@ LL | for _ in 0..5 {}
1915
| ^^^^
2016
|
2117
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
22-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
23-
|
24-
LL + #![feature(const_trait_impl)]
25-
|
2618

2719
error: aborting due to 2 previous errors
2820

tests/ui/consts/const-try-feature-gate.stderr

-8
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ LL | Some(())?;
1717
note: impl defined here, but it is not `const`
1818
--> $SRC_DIR/core/src/option.rs:LL:COL
1919
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
20-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
21-
|
22-
LL + #![feature(const_trait_impl)]
23-
|
2420

2521
error[E0015]: `?` cannot convert from residual of `Option<()>` in constant functions
2622
--> $DIR/const-try-feature-gate.rs:4:5
@@ -31,10 +27,6 @@ LL | Some(())?;
3127
note: impl defined here, but it is not `const`
3228
--> $SRC_DIR/core/src/option.rs:LL:COL
3329
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
34-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
35-
|
36-
LL + #![feature(const_trait_impl)]
37-
|
3830

3931
error: aborting due to 3 previous errors
4032

tests/ui/consts/const-try.rs

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ impl const Try for TryMe {
3434

3535
const fn t() -> TryMe {
3636
TryMe?;
37+
//~^ ERROR `?` cannot determine the branch of `TryMe` in constant functions
38+
//~| ERROR `?` cannot convert from residual of `TryMe` in constant functions
3739
TryMe
3840
}
3941

tests/ui/consts/const-try.stderr

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,22 @@ LL | impl const Try for TryMe {
1616
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
1717
= note: adding a non-const method body in the future would be a breaking change
1818

19-
error: aborting due to 2 previous errors
19+
error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions
20+
--> $DIR/const-try.rs:36:5
21+
|
22+
LL | TryMe?;
23+
| ^^^^^^
24+
|
25+
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
26+
27+
error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions
28+
--> $DIR/const-try.rs:36:5
29+
|
30+
LL | TryMe?;
31+
| ^^^^^^
32+
|
33+
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
34+
35+
error: aborting due to 4 previous errors
2036

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

tests/ui/consts/const_cmp_type_id.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//@ check-pass
21
//@ compile-flags: -Znext-solver
32
#![feature(const_type_id, const_trait_impl, effects)]
43
#![allow(incomplete_features)]
@@ -7,11 +6,13 @@ use std::any::TypeId;
76

87
fn main() {
98
const {
10-
// FIXME(effects) this isn't supposed to pass (right now) but it did.
11-
// revisit binops typeck please.
129
assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
10+
//~^ ERROR cannot call non-const operator in constants
1311
assert!(TypeId::of::<()>() != TypeId::of::<u8>());
12+
//~^ ERROR cannot call non-const operator in constants
1413
let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
14+
//~^ ERROR cannot call non-const operator in constants
1515
// can't assert `_a` because it is not deterministic
16+
// FIXME(effects) make it pass
1617
}
1718
}
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0015]: cannot call non-const operator in constants
2+
--> $DIR/const_cmp_type_id.rs:9:17
3+
|
4+
LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: impl defined here, but it is not `const`
8+
--> $SRC_DIR/core/src/any.rs:LL:COL
9+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
10+
11+
error[E0015]: cannot call non-const operator in constants
12+
--> $DIR/const_cmp_type_id.rs:11:17
13+
|
14+
LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>());
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
|
17+
note: impl defined here, but it is not `const`
18+
--> $SRC_DIR/core/src/any.rs:LL:COL
19+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
20+
21+
error[E0015]: cannot call non-const operator in constants
22+
--> $DIR/const_cmp_type_id.rs:13:18
23+
|
24+
LL | let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26+
|
27+
note: impl defined here, but it is not `const`
28+
--> $SRC_DIR/core/src/any.rs:LL:COL
29+
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
30+
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
31+
32+
error: aborting due to 3 previous errors
33+
34+
For more information about this error, try `rustc --explain E0015`.

tests/ui/consts/control-flow/loop.stderr

-16
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ LL | for i in 0..4 {
3535
note: impl defined here, but it is not `const`
3636
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
3737
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
38-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
39-
|
40-
LL + #![feature(const_trait_impl)]
41-
|
4238

4339
error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
4440
--> $DIR/loop.rs:53:14
@@ -47,10 +43,6 @@ LL | for i in 0..4 {
4743
| ^^^^
4844
|
4945
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
50-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
51-
|
52-
LL + #![feature(const_trait_impl)]
53-
|
5446

5547
error[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants
5648
--> $DIR/loop.rs:59:14
@@ -61,10 +53,6 @@ LL | for i in 0..4 {
6153
note: impl defined here, but it is not `const`
6254
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
6355
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
64-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
65-
|
66-
LL + #![feature(const_trait_impl)]
67-
|
6856

6957
error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
7058
--> $DIR/loop.rs:59:14
@@ -73,10 +61,6 @@ LL | for i in 0..4 {
7361
| ^^^^
7462
|
7563
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
76-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
77-
|
78-
LL + #![feature(const_trait_impl)]
79-
|
8064

8165
error: aborting due to 6 previous errors
8266

tests/ui/consts/control-flow/try.stderr

-8
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ LL | x?;
1717
note: impl defined here, but it is not `const`
1818
--> $SRC_DIR/core/src/option.rs:LL:COL
1919
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
20-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
21-
|
22-
LL + #![feature(const_trait_impl)]
23-
|
2420

2521
error[E0015]: `?` cannot convert from residual of `Option<i32>` in constant functions
2622
--> $DIR/try.rs:6:5
@@ -31,10 +27,6 @@ LL | x?;
3127
note: impl defined here, but it is not `const`
3228
--> $SRC_DIR/core/src/option.rs:LL:COL
3329
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
34-
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
35-
|
36-
LL + #![feature(const_trait_impl)]
37-
|
3830

3931
error: aborting due to 3 previous errors
4032

0 commit comments

Comments
 (0)