diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2021-12-18 14:49:42 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-12-18 14:49:42 +0100 |
| commit | cc043aa75f67ae7609fcc915982d0e0e9c3f712c (patch) | |
| tree | 91f4eda838c2518b319dbf17e8511eac4e3b1b89 | |
| parent | 53a95ea289941ffeacb95f2ca7a7a7f1a9aae679 (diff) | |
| parent | a1f91aa4104c330d5592c56653a1c68394251120 (diff) | |
| download | rust-cc043aa75f67ae7609fcc915982d0e0e9c3f712c.tar.gz rust-cc043aa75f67ae7609fcc915982d0e0e9c3f712c.zip | |
Rollup merge of #92037 - fee1-dead:fix_env_dmbic, r=oli-obk
Use a const ParamEnv when in default_method_body_is_const
r? `@oli-obk`
This PR fixes the param_env function to return `constness: Const` correctly for trait methods marked with `#[default_method_body_is_const]`. The snippet below is erroneously accepted by the compiler and has been fixed by this change. ([Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=12dc6681b2eeee5f604203d96259eeb4))
```rust
#![feature(const_fn_trait_bound)]
#![feature(const_trait_impl)]
trait Tr {}
impl Tr for () {}
const fn foo<T>() where T: ~const Tr {}
pub trait Foo {
#[default_method_body_is_const]
fn foo() {
foo::<()>();
}
}
```
3 files changed, 43 insertions, 1 deletions
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index a2d14545916..6c2657bd64b 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -3,7 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, Binder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt}; -use rustc_span::Span; +use rustc_span::{sym, Span}; use rustc_trait_selection::traits; fn sized_constraint_for_ty<'tcx>( @@ -285,6 +285,12 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let constness = match hir_id { Some(hir_id) => match tcx.hir().get(hir_id) { + hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) + if tcx.has_attr(def_id, sym::default_method_body_is_const) => + { + hir::Constness::Const + } + hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. }) | hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. }) | hir::Node::TraitItem(hir::TraitItem { diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs new file mode 100644 index 00000000000..7db04fe1ac3 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs @@ -0,0 +1,17 @@ +#![feature(const_fn_trait_bound)] +#![feature(const_trait_impl)] + +trait Tr {} +impl Tr for () {} + +const fn foo<T>() where T: ~const Tr {} + +pub trait Foo { + #[default_method_body_is_const] + fn foo() { + foo::<()>(); + //~^ ERROR the trait bound `(): Tr` is not satisfied + } +} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr new file mode 100644 index 00000000000..6e7e4b3a472 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `(): Tr` is not satisfied + --> $DIR/default-method-body-is-const-body-checking.rs:12:15 + | +LL | foo::<()>(); + | ^^ the trait `Tr` is not implemented for `()` + | +note: required by a bound in `foo` + --> $DIR/default-method-body-is-const-body-checking.rs:7:28 + | +LL | const fn foo<T>() where T: ~const Tr {} + | ^^^^^^^^^ required by this bound in `foo` +help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement + | +LL | pub trait Foo where (): Tr { + | ++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |
