Auto merge of #143879 - fee1-dead-contrib:push-lrlpoouyqqry, r=fmease

parse `const trait Trait`

r? oli-obk or anyone from project-const-traits

cc `@rust-lang/project-const-traits`
This commit is contained in:
bors
2025-07-17 15:54:33 +00:00
94 changed files with 365 additions and 299 deletions
+3 -6
View File
@@ -67,10 +67,8 @@ in [`wfcheck::check_impl`].
Here's an example:
```rust
#[const_trait]
trait Bar {}
#[const_trait]
trait Foo: ~const Bar {}
const trait Bar {}
const trait Foo: ~const Bar {}
// `const_conditions` contains `HostEffect(Self: Bar, maybe)`
impl const Bar for () {}
@@ -85,8 +83,7 @@ predicates of the trait method, and we attempt to prove the predicates of the
impl method. We do the same for `const_conditions`:
```rust
#[const_trait]
trait Foo {
const trait Foo {
fn hi<T: ~const Default>();
}
+1 -1
View File
@@ -2865,7 +2865,7 @@ fn get_name(
ItemKind::Fn { ref sig, generics, body: body_id, .. } => {
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
}
ItemKind::Trait(_, _, _, generics, bounds, item_ids) => {
ItemKind::Trait(_, _, _, _, generics, bounds, item_ids) => {
let items = item_ids
.iter()
.map(|&ti| clean_trait_item(cx.tcx.hir_trait_item(ti), cx))
+1 -1
View File
@@ -648,7 +648,7 @@ fn build_fn_header(
let sig = tcx.fn_sig(def_id).skip_binder();
let constness = if tcx.is_const_fn(def_id) {
// rustc's `is_const_fn` returns `true` for associated functions that have an `impl const` parent
// or that have a `#[const_trait]` parent. Do not display those as `const` in rustdoc because we
// or that have a `const trait` parent. Do not display those as `const` in rustdoc because we
// won't be printing correct syntax plus the syntax is unstable.
match tcx.opt_associated_item(def_id) {
Some(ty::AssocItem {
@@ -306,7 +306,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
cur_f = Some(field);
}
},
ItemKind::Trait(is_auto, _safety, _ident, _generics, _generic_bounds, item_ref)
ItemKind::Trait(_constness, is_auto, _safety, _ident, _generics, _generic_bounds, item_ref)
if self.enable_ordering_for_trait && *is_auto == IsAuto::No =>
{
let mut cur_t: Option<(TraitItemId, Ident)> = None;
+1 -1
View File
@@ -740,7 +740,7 @@ fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute])
);
}
},
ItemKind::Trait(_, unsafety, ..) => match (headers.safety, unsafety) {
ItemKind::Trait(_, _, unsafety, ..) => match (headers.safety, unsafety) {
(false, Safety::Unsafe) => span_lint(
cx,
MISSING_SAFETY_DOC,
@@ -125,7 +125,7 @@
impl<'tcx> LateLintPass<'tcx> for LenZero {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
if let ItemKind::Trait(_, _, ident, _, _, trait_items) = item.kind
if let ItemKind::Trait(_, _, _, ident, _, _, trait_items) = item.kind
&& !item.span.from_expansion()
{
check_trait_items(cx, item, ident, trait_items);
@@ -101,7 +101,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
let attrs = cx.tcx.hir_attrs(it.hir_id());
check_missing_inline_attrs(cx, attrs, it.span, desc);
},
hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _ident, _generics, _bounds, trait_items) => {
hir::ItemKind::Trait(ref _constness, ref _is_auto, ref _unsafe, _ident, _generics, _bounds, trait_items) => {
// note: we need to check if the trait is exported so we can't use
// `LateLintPass::check_trait_item` here.
for &tit in trait_items {
@@ -112,7 +112,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
// special handling for self trait bounds as these are not considered generics
// ie. trait Foo: Display {}
if let Item {
kind: ItemKind::Trait(_, _, _, _, bounds, ..),
kind: ItemKind::Trait(_, _, _, _, _, bounds, ..),
..
} = item
{
@@ -133,7 +133,7 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tc
..
}) = segments.first()
&& let Some(Node::Item(Item {
kind: ItemKind::Trait(_, _, _, _, self_bounds, _),
kind: ItemKind::Trait(_, _, _, _, _, self_bounds, _),
..
})) = cx.tcx.hir_get_if_local(*def_id)
{
@@ -131,7 +131,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, it: &Item<'_>) {
return;
}
match it.kind {
ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, ident, ..) => {
ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, _, ident, ..) => {
check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive);
},
ItemKind::Enum(ident, _, ref enumdef) => {
@@ -444,6 +444,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
},
(
Trait(box ast::Trait {
constness: lc,
is_auto: la,
safety: lu,
ident: li,
@@ -452,6 +453,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
items: lis,
}),
Trait(box ast::Trait {
constness: rc,
is_auto: ra,
safety: ru,
ident: ri,
@@ -460,7 +462,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
items: ris,
}),
) => {
la == ra
matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)
&& la == ra
&& matches!(lu, Safety::Default) == matches!(ru, Safety::Default)
&& eq_id(*li, *ri)
&& eq_generics(lg, rg)
@@ -252,11 +252,11 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
ItemKind::Struct(_, _, VariantData::Struct { .. }) => (Pat::Str("struct"), Pat::Str("}")),
ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")),
ItemKind::Trait(_, Safety::Unsafe, ..)
ItemKind::Trait(_, _, Safety::Unsafe, ..)
| ItemKind::Impl(Impl {
safety: Safety::Unsafe, ..
}) => (Pat::Str("unsafe"), Pat::Str("}")),
ItemKind::Trait(IsAuto::Yes, ..) => (Pat::Str("auto"), Pat::Str("}")),
ItemKind::Trait(_, IsAuto::Yes, ..) => (Pat::Str("auto"), Pat::Str("}")),
ItemKind::Trait(..) => (Pat::Str("trait"), Pat::Str("}")),
ItemKind::Impl(_) => (Pat::Str("impl"), Pat::Str("}")),
_ => return (Pat::Str(""), Pat::Str("")),
+1 -2
View File
@@ -84,8 +84,7 @@ mod issue14871 {
const ONE: Self;
}
#[const_trait]
pub trait NumberConstants {
pub const trait NumberConstants {
fn constant(value: usize) -> Self;
}
+1 -2
View File
@@ -84,8 +84,7 @@ pub trait Number: Copy + Add<Self, Output = Self> + AddAssign {
const ONE: Self;
}
#[const_trait]
pub trait NumberConstants {
pub const trait NumberConstants {
fn constant(value: usize) -> Self;
}
@@ -3,8 +3,7 @@
// Reduced test case from https://github.com/rust-lang/rust-clippy/issues/14658
#[const_trait]
trait ConstTrait {
const trait ConstTrait {
fn method(self);
}
@@ -3,8 +3,7 @@
// Reduced test case from https://github.com/rust-lang/rust-clippy/issues/14658
#[const_trait]
trait ConstTrait {
const trait ConstTrait {
fn method(self);
}
@@ -1,5 +1,5 @@
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/const_trait.rs:24:1
--> tests/ui/missing_const_for_fn/const_trait.rs:23:1
|
LL | / fn can_be_const() {
LL | | 0u64.method();
@@ -167,8 +167,7 @@ where
}
// #13476
#[const_trait]
trait ConstTrait {}
const trait ConstTrait {}
const fn const_trait_bounds_good<T: ConstTrait + [const] ConstTrait>() {}
const fn const_trait_bounds_bad<T: [const] ConstTrait>() {}
@@ -167,8 +167,7 @@ fn assoc_tys_generics<'a, 'b, T, U>()
}
// #13476
#[const_trait]
trait ConstTrait {}
const trait ConstTrait {}
const fn const_trait_bounds_good<T: ConstTrait + [const] ConstTrait>() {}
const fn const_trait_bounds_bad<T: [const] ConstTrait + [const] ConstTrait>() {}
@@ -59,19 +59,19 @@ LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) {
| ^^^^^^^^^^^^^^^^^ help: try: `Any + Send`
error: these bounds contain repeated elements
--> tests/ui/trait_duplication_in_bounds.rs:174:36
--> tests/ui/trait_duplication_in_bounds.rs:173:36
|
LL | const fn const_trait_bounds_bad<T: [const] ConstTrait + [const] ConstTrait>() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[const] ConstTrait`
error: these where clauses contain repeated elements
--> tests/ui/trait_duplication_in_bounds.rs:181:8
--> tests/ui/trait_duplication_in_bounds.rs:180:8
|
LL | T: IntoIterator<Item = U::Owned> + IntoIterator<Item = U::Owned>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator<Item = U::Owned>`
error: these where clauses contain repeated elements
--> tests/ui/trait_duplication_in_bounds.rs:203:8
--> tests/ui/trait_duplication_in_bounds.rs:202:8
|
LL | T: AssocConstTrait<ASSOC = 0> + AssocConstTrait<ASSOC = 0>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait<ASSOC = 0>`
@@ -1011,8 +1011,7 @@ pub trait Add<Rhs = Self> {
}
#[lang = "add_assign"]
#[const_trait]
pub trait AddAssign<Rhs = Self> {
pub const trait AddAssign<Rhs = Self> {
fn add_assign(&mut self, rhs: Rhs);
}
+3 -1
View File
@@ -1172,6 +1172,7 @@ pub(crate) fn format_trait(
unreachable!();
};
let ast::Trait {
constness,
is_auto,
safety,
ident,
@@ -1182,7 +1183,8 @@ pub(crate) fn format_trait(
let mut result = String::with_capacity(128);
let header = format!(
"{}{}{}trait ",
"{}{}{}{}trait ",
format_constness(constness),
format_visibility(context, &item.vis),
format_safety(safety),
format_auto(is_auto),