Skip to content

Commit

Permalink
Deny calls to non-#[const_trait] methods in MIR constck
Browse files Browse the repository at this point in the history
  • Loading branch information
fee1-dead committed Oct 26, 2024
1 parent 54761cb commit f2f6723
Show file tree
Hide file tree
Showing 75 changed files with 438 additions and 324 deletions.
29 changes: 19 additions & 10 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,14 +616,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {

let mut is_trait = false;
// Attempting to call a trait method?
if tcx.trait_of_item(callee).is_some() {
if let Some(trait_did) = tcx.trait_of_item(callee) {
trace!("attempting to call a trait method");

let trait_is_const = tcx.is_const_trait(trait_did);
// trait method calls are only permitted when `effects` is enabled.
// we don't error, since that is handled by typeck. We try to resolve
// the trait into the concrete method, and uses that for const stability
// checks.
// typeck ensures the conditions for calling a const trait method are met,
// so we only error if the trait isn't const. We try to resolve the trait
// into the concrete method, and uses that for const stability checks.
// FIXME(effects) we might consider moving const stability checks to typeck as well.
if tcx.features().effects() {
if tcx.features().effects() && trait_is_const {
// This skips the check below that ensures we only call `const fn`.
is_trait = true;

Expand All @@ -638,17 +640,24 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
callee = def;
}
} else {
// if the trait is const but the user has not enabled the feature(s),
// suggest them.
let feature = if trait_is_const {
Some(if tcx.features().const_trait_impl() {
sym::effects
} else {
sym::const_trait_impl
})
} else {
None
};
self.check_op(ops::FnCallNonConst {
caller,
callee,
args: fn_args,
span: *fn_span,
call_source,
feature: Some(if tcx.features().const_trait_impl() {
sym::effects
} else {
sym::const_trait_impl
}),
feature,
});
// If we allowed this, we're in miri-unleashed mode, so we might
// as well skip the remaining checks.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ LL + #[derive(ConstParamTy)]
LL | struct Foo(u8);
|

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

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

error[E0284]: type annotations needed: cannot normalize `foo<N>::{constant#0}`
--> $DIR/unify-op-with-fn-call.rs:21:11
error[E0015]: cannot call non-const fn `<Foo as Add>::add` in constants
--> $DIR/unify-op-with-fn-call.rs:21:13
|
LL | bar::<{ std::ops::Add::add(N, N) }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `foo<N>::{constant#0}`
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const fn `<usize as Add>::add` in constants
--> $DIR/unify-op-with-fn-call.rs:30:14
|
LL | bar2::<{ std::ops::Add::add(N, N) }>();
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

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

error: aborting due to 9 previous errors
error: aborting due to 10 previous errors

Some errors have detailed explanations: E0284, E0741.
For more information about an error, try `rustc --explain E0284`.
Some errors have detailed explanations: E0015, E0284, E0741.
For more information about an error, try `rustc --explain E0015`.
4 changes: 0 additions & 4 deletions tests/ui/const-generics/issue-93647.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ LL | (||1usize)()
|
= note: closures need an RFC before allowed to be called in constants
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

error: aborting due to 1 previous error

Expand Down
8 changes: 0 additions & 8 deletions tests/ui/const-generics/issues/issue-90318.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ LL | If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

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

error: aborting due to 4 previous errors

Expand Down
6 changes: 3 additions & 3 deletions tests/ui/consts/closure-in-foreign-crate.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//@ aux-build:closure-in-foreign-crate.rs
// FIXME(effects) aux-build:closure-in-foreign-crate.rs
//@ build-pass

extern crate closure_in_foreign_crate;
// FIXME(effects) extern crate closure_in_foreign_crate;

const _: () = closure_in_foreign_crate::test();
// FIXME(effects) const _: () = closure_in_foreign_crate::test();

fn main() {}
8 changes: 0 additions & 8 deletions tests/ui/consts/const-fn-error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ LL | for i in 0..x {
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

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

error: aborting due to 3 previous errors

Expand Down
8 changes: 0 additions & 8 deletions tests/ui/consts/const-for-feature-gate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ LL | for _ in 0..5 {}
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

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

error: aborting due to 3 previous errors

Expand Down
8 changes: 0 additions & 8 deletions tests/ui/consts/const-for.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ LL | for _ in 0..5 {}
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

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

error: aborting due to 2 previous errors

Expand Down
8 changes: 0 additions & 8 deletions tests/ui/consts/const-try-feature-gate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ LL | Some(())?;
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/option.rs:LL:COL
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

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

error: aborting due to 3 previous errors

Expand Down
2 changes: 2 additions & 0 deletions tests/ui/consts/const-try.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ impl const Try for TryMe {

const fn t() -> TryMe {
TryMe?;
//~^ ERROR `?` cannot determine the branch of `TryMe` in constant functions
//~| ERROR `?` cannot convert from residual of `TryMe` in constant functions
TryMe
}

Expand Down
19 changes: 18 additions & 1 deletion tests/ui/consts/const-try.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,22 @@ LL | impl const Try for TryMe {
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
= note: adding a non-const method body in the future would be a breaking change

error: aborting due to 2 previous errors
error[E0015]: `?` cannot determine the branch of `TryMe` in constant functions
--> $DIR/const-try.rs:36:5
|
LL | TryMe?;
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions
--> $DIR/const-try.rs:36:5
|
LL | TryMe?;
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0015`.
7 changes: 4 additions & 3 deletions tests/ui/consts/const_cmp_type_id.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//@ check-pass
//@ compile-flags: -Znext-solver
#![feature(const_type_id, const_trait_impl, effects)]
#![allow(incomplete_features)]
Expand All @@ -7,11 +6,13 @@ use std::any::TypeId;

fn main() {
const {
// FIXME(effects) this isn't supposed to pass (right now) but it did.
// revisit binops typeck please.
assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
//~^ ERROR cannot call non-const operator in constants
assert!(TypeId::of::<()>() != TypeId::of::<u8>());
//~^ ERROR cannot call non-const operator in constants
let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
//~^ ERROR cannot call non-const operator in constants
// can't assert `_a` because it is not deterministic
// FIXME(effects) make it pass
}
}
34 changes: 34 additions & 0 deletions tests/ui/consts/const_cmp_type_id.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
error[E0015]: cannot call non-const operator in constants
--> $DIR/const_cmp_type_id.rs:9:17
|
LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const operator in constants
--> $DIR/const_cmp_type_id.rs:11:17
|
LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const operator in constants
--> $DIR/const_cmp_type_id.rs:13:18
|
LL | let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0015`.
16 changes: 0 additions & 16 deletions tests/ui/consts/control-flow/loop.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@ LL | for i in 0..4 {
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

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

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

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

error: aborting due to 6 previous errors

Expand Down
8 changes: 0 additions & 8 deletions tests/ui/consts/control-flow/try.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ LL | x?;
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/option.rs:LL:COL
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
|

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

error: aborting due to 3 previous errors

Expand Down
Loading

0 comments on commit f2f6723

Please sign in to comment.