Generate const predicates for const trait aliases

This commit is contained in:
Oli Scherer
2025-07-21 11:35:45 +00:00
committed by Oli Scherer
parent 5f6772c2a7
commit 8b122f1e11
7 changed files with 47 additions and 87 deletions

View File

@@ -1192,6 +1192,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait);
});
}
ItemKind::TraitAlias(box TraitAlias { constness, generics, bounds, .. }) => {
let disallowed = matches!(constness, ast::Const::No)
.then(|| TildeConstReason::Trait { span: item.span });
self.with_tilde_const(disallowed, |this| {
this.visit_generics(generics);
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
});
}
ItemKind::Mod(safety, ident, mod_kind) => {
if let &Safety::Unsafe(span) = safety {
self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });

View File

@@ -847,7 +847,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
hir::ItemKind::Trait(constness, is_auto, safety, ..) => {
(constness, false, is_auto == hir::IsAuto::Yes, safety)
}
hir::ItemKind::TraitAlias(..) => (hir::Constness::NotConst, true, false, hir::Safety::Safe),
hir::ItemKind::TraitAlias(constness, ..) => (constness, true, false, hir::Safety::Safe),
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
};

View File

@@ -1031,7 +1031,8 @@ pub(super) fn const_conditions<'tcx>(
Node::Item(item) => match item.kind {
hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
hir::ItemKind::Fn { generics, .. } => (generics, None, false),
hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => {
hir::ItemKind::TraitAlias(_, _, generics, supertraits)
| hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => {
(generics, Some((item.owner_id.def_id, supertraits)), false)
}
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
@@ -1143,13 +1144,14 @@ pub(super) fn explicit_implied_const_bounds<'tcx>(
span_bug!(tcx.def_span(def_id), "RPITIT in impl should not have item bounds")
}
None => match tcx.hir_node_by_def_id(def_id) {
Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => {
implied_predicates_with_filter(
tcx,
def_id.to_def_id(),
PredicateFilter::SelfConstIfConst,
)
}
Node::Item(hir::Item {
kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..),
..
}) => implied_predicates_with_filter(
tcx,
def_id.to_def_id(),
PredicateFilter::SelfConstIfConst,
),
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
| Node::OpaqueTy(_) => {
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)

View File

@@ -2101,7 +2101,7 @@ impl<'tcx> TyCtxt<'tcx> {
DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => {
self.constness(def_id) == hir::Constness::Const
}
DefKind::Trait => self.is_const_trait(def_id),
DefKind::TraitAlias | DefKind::Trait => self.is_const_trait(def_id),
DefKind::AssocTy => {
let parent_def_id = self.parent(def_id);
match self.def_kind(parent_def_id) {
@@ -2144,7 +2144,6 @@ impl<'tcx> TyCtxt<'tcx> {
| DefKind::Variant
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::TyParam
| DefKind::Const
| DefKind::ConstParam

View File

@@ -1,46 +1,23 @@
error: `[const]` is not allowed here
--> $DIR/trait_alias.rs:14:19
|
LL | const trait Foo = [const] Bar + Baz;
| ^^^^^^^
|
= note: this item cannot have `[const]` trait bounds
error: `[const]` can only be applied to `const` traits
--> $DIR/trait_alias.rs:17:17
|
LL | const fn foo<T: [const] Foo>(x: &T) {
| ^^^^^^^ can't be applied to `Foo`
|
help: mark `Foo` as `const` to allow it to have `const` implementations
|
LL | #[const_trait] const trait Foo = [const] Bar + Baz;
| ++++++++++++++
error: `[const]` can only be applied to `const` traits
--> $DIR/trait_alias.rs:17:17
|
LL | const fn foo<T: [const] Foo>(x: &T) {
| ^^^^^^^ can't be applied to `Foo`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: mark `Foo` as `const` to allow it to have `const` implementations
|
LL | #[const_trait] const trait Foo = [const] Bar + Baz;
| ++++++++++++++
error[E0277]: the trait bound `T: [const] Bar` is not satisfied
--> $DIR/trait_alias.rs:20:7
|
LL | x.bar();
| ^^^
error[E0277]: the trait bound `T: [const] Baz` is not satisfied
--> $DIR/trait_alias.rs:24:11
--> $DIR/trait_alias.rs:20:11
|
LL | x.baz();
| ^^^
error: aborting due to 5 previous errors
error[E0277]: the trait bound `(): const Foo` is not satisfied
--> $DIR/trait_alias.rs:25:19
|
LL | const _: () = foo(&());
| --- ^^^
| |
| required by a bound introduced by this call
|
note: required by a bound in `foo`
--> $DIR/trait_alias.rs:16:17
|
LL | const fn foo<T: [const] Foo>(x: &T) {
| ^^^^^^^^^^^ required by this bound in `foo`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@@ -1,40 +1,17 @@
error: `[const]` is not allowed here
--> $DIR/trait_alias.rs:14:19
error[E0277]: the trait bound `(): const Foo` is not satisfied
--> $DIR/trait_alias.rs:25:19
|
LL | const trait Foo = [const] Bar + Baz;
| ^^^^^^^
LL | const _: () = foo(&());
| --- ^^^
| |
| required by a bound introduced by this call
|
= note: this item cannot have `[const]` trait bounds
error: `[const]` can only be applied to `const` traits
--> $DIR/trait_alias.rs:17:17
note: required by a bound in `foo`
--> $DIR/trait_alias.rs:16:17
|
LL | const fn foo<T: [const] Foo>(x: &T) {
| ^^^^^^^ can't be applied to `Foo`
|
help: mark `Foo` as `const` to allow it to have `const` implementations
|
LL | #[const_trait] const trait Foo = [const] Bar + Baz;
| ++++++++++++++
| ^^^^^^^^^^^ required by this bound in `foo`
error: `[const]` can only be applied to `const` traits
--> $DIR/trait_alias.rs:17:17
|
LL | const fn foo<T: [const] Foo>(x: &T) {
| ^^^^^^^ can't be applied to `Foo`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: mark `Foo` as `const` to allow it to have `const` implementations
|
LL | #[const_trait] const trait Foo = [const] Bar + Baz;
| ++++++++++++++
error[E0277]: the trait bound `T: [const] Bar` is not satisfied
--> $DIR/trait_alias.rs:20:7
|
LL | x.bar();
| ^^^
error: aborting due to 4 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@@ -12,13 +12,9 @@ impl const Bar for () {}
impl const Baz for () {}
const trait Foo = [const] Bar + Baz;
//~^ ERROR: `[const]` is not allowed here
const fn foo<T: [const] Foo>(x: &T) {
//~^ ERROR: `[const]` can only be applied to `const` traits
//~| ERROR: `[const]` can only be applied to `const` traits
x.bar();
//~^ ERROR: the trait bound `T: [const] Bar` is not satisfied
#[cfg(fail)]
{
x.baz();
@@ -27,5 +23,6 @@ const fn foo<T: [const] Foo>(x: &T) {
}
const _: () = foo(&());
//~^ ERROR: `(): const Foo` is not satisfied
fn main() {}