Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,8 +774,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {

// Attempting to call a trait method?
if let Some(trait_did) = tcx.trait_of_assoc(callee) {
// We can't determine the actual callee here, so we have to do different checks
// than usual.
// We can't determine the actual callee (the underlying impl of the trait) here, so we have
// to do different checks than usual.

trace!("attempting to call a trait method");
let is_const = tcx.constness(callee) == hir::Constness::Const;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,7 +1333,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_non_const_trait_method, AttributeType::Normal, template!(Word),
ErrorFollowing, EncodeCrossCrate::No,
"`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods \
as non-const to allow large traits to easier transition to const"
as non-const to allow large traits an easier transition to const"
),

BuiltinAttribute {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ fn compare_method_predicate_entailment<'tcx>(
trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate),
);

let is_conditionally_const = tcx.is_conditionally_const(impl_def_id);
let is_conditionally_const = tcx.is_conditionally_const(impl_m.def_id);
if is_conditionally_const {
// Augment the hybrid param-env with the const conditions
// of the impl header and the trait method.
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2181,7 +2181,9 @@ impl<'tcx> TyCtxt<'tcx> {
self.constness(def_id) == hir::Constness::Const
}
DefKind::Impl { of_trait: true } => {
let Some(trait_method_did) = self.trait_item_of(def_id) else { return false; };
let Some(trait_method_did) = self.trait_item_of(def_id) else {
return false;
};
self.constness(trait_method_did) == hir::Constness::Const
&& self.is_conditionally_const(parent_def_id)
}
Expand Down
2 changes: 1 addition & 1 deletion src/doc/rustc-dev-guide/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@
- [Inference details](./opaque-types-impl-trait-inference.md)
- [Return Position Impl Trait In Trait](./return-position-impl-trait-in-trait.md)
- [Region inference restrictions][opaque-infer]
- [Const condition checking](./effects.md)
- [Const traits and const condition checking](./effects.md)
- [Pattern and exhaustiveness checking](./pat-exhaustive-checking.md)
- [Unsafety checking](./unsafety-checking.md)
- [MIR dataflow](./mir/dataflow.md)
Expand Down
17 changes: 16 additions & 1 deletion src/doc/rustc-dev-guide/src/effects.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Effects and const condition checking
# Effects, const traits, and const condition checking

## The `HostEffect` predicate

Expand Down Expand Up @@ -154,3 +154,18 @@ be dropped at compile time.

[old solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_trait_selection/traits/effects.rs.html
[new trait solver]: https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_next_trait_solver/solve/effect_goals.rs.html

## More on const traits

To be expanded later.

### The `#[rustc_non_const_trait_method]` attribute

This is intended for internal (standard library) usage only. With this attribute
applied to a trait method, the compiler will not check the default body of this
method for ability to run in compile time. Users of the trait will also not be
allowed to use this trait method in const contexts. This attribute is primarily
used for constifying large traits such as `Iterator` without having to make all
its methods `const` at the same time.

This attribute should not be present while stabilizing the trait as `const`.
2 changes: 1 addition & 1 deletion tests/ui/traits/const-traits/partial/attr-gate.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LL | #[rustc_non_const_trait_method]
|
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
= note: the `#[rustc_non_const_trait_method]` attribute is an internal implementation detail that will never be stable
= note: `#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods as non-const to allow large traits to easier transition to const
= note: `#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods as non-const to allow large traits an easier transition to const

error: aborting due to 1 previous error

Expand Down
9 changes: 9 additions & 0 deletions tests/ui/traits/const-traits/partial/no-const-callers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,22 @@ impl const A for () {
fn a() {}
}

impl const A for u8 {
fn a() {}
fn b() { println!("hello"); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a test for impling the method constly. That's an odd situation, but not a problem since we don't allow stabilizing traits that have such methods

//~^ ERROR: cannot call non-const function
}

const fn foo<T: [const] A>() {
T::a();
T::b();
//~^ ERROR: cannot call non-const associated function
<()>::a();
<()>::b();
//~^ ERROR: cannot call non-const associated function
u8::a();
u8::b();
//~^ ERROR: cannot call non-const associated function
}

fn main() {}
25 changes: 22 additions & 3 deletions tests/ui/traits/const-traits/partial/no-const-callers.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
error[E0015]: cannot call non-const function `std::io::_print` in constant functions
--> $DIR/no-const-callers.rs:15:14
|
LL | fn b() { println!("hello"); }
| ^^^^^^^^^^^^^^^^^
|
note: function `_print` is not const
--> $SRC_DIR/std/src/io/stdio.rs:LL:COL
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0015]: cannot call non-const associated function `<T as A>::b` in constant functions
--> $DIR/no-const-callers.rs:15:5
--> $DIR/no-const-callers.rs:21:5
|
LL | T::b();
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error[E0015]: cannot call non-const associated function `<() as A>::b` in constant functions
--> $DIR/no-const-callers.rs:18:5
--> $DIR/no-const-callers.rs:24:5
|
LL | <()>::b();
| ^^^^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error: aborting due to 2 previous errors
error[E0015]: cannot call non-const associated function `<u8 as A>::b` in constant functions
--> $DIR/no-const-callers.rs:27:5
|
LL | u8::b();
| ^^^^^^^
|
= 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`.
Loading