Skip to content

Commit 18aa883

Browse files
authored
Rollup merge of rust-lang#132169 - fee1-dead-contrib:consttraitsck, r=compiler-errors
Deny calls to non-`#[const_trait]` methods in MIR constck This is a (potentially temporary) fix that closes off the mismatch in assumptions between MIR constck and typeck which does the const traits checking. Before this PR, MIR constck assumed that typeck correctly handled all calls to trait methods in const contexts if effects is enabled. That is not true because typeck only correctly handles callees that are const. For non-const callees (such as methods in a non-const_trait), typeck had never created an error. https://github.com/rust-lang/rust/blob/45089ec19ebebec88bace6ec237244ff0eaa7ad3/compiler/rustc_hir_typeck/src/callee.rs#L876-L877 I called this potentially temporary because the const checks could be moved to HIR entirely. Alongside the recent refactor in const stability checks where that component could be placed would need more discussion. (cc `@compiler-errors` `@RalfJung)` Tests are updated, mainly due to traits not being const in core, so tests that call them correctly error. This fixes rust-lang/project-const-traits#12.
2 parents a72b321 + f2f6723 commit 18aa883

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)