From 56211738ea8e5b5ca0d5b460a73944f0618aaa4f Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Sun, 19 Apr 2026 01:16:23 +0900 Subject: [PATCH 1/7] Reorder keywords to place restrictions next to visibility --- compiler/rustc_parse/src/parser/item.rs | 122 ++++++++++-------------- 1 file changed, 49 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index ccfc9438f1ccf..0be16e35b7b35 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1052,80 +1052,58 @@ impl<'a> Parser<'a> { } } - /// Is there an `[ impl(in? path) ]? trait` item `dist` tokens ahead? - fn is_trait_with_maybe_impl_restriction_in_front(&self, dist: usize) -> bool { - // `trait` - if self.is_keyword_ahead(dist, &[kw::Trait]) { - return true; - } - // `impl(` - if !self.is_keyword_ahead(dist, &[kw::Impl]) - || !self.look_ahead(dist + 1, |t| t == &token::OpenParen) - { - return false; - } - // `crate | super | self) trait` - if self.is_keyword_ahead(dist + 2, &[kw::Crate, kw::Super, kw::SelfLower]) - && self.look_ahead(dist + 3, |t| t == &token::CloseParen) - && self.is_keyword_ahead(dist + 4, &[kw::Trait]) - { - return true; - } - // `impl(in? something) trait` - // We catch cases where the `in` keyword is missing to provide a - // better error message. This is handled later in - // `self.recover_incorrect_impl_restriction`. - self.tree_look_ahead(dist + 2, |t| { - if let TokenTree::Token(token, _) = t { token.is_keyword(kw::Trait) } else { false } - }) - .unwrap_or(false) - } - - /// Is this an `(const unsafe? auto? [ impl(in? path) ]? | unsafe auto? [ impl(in? path) ]? | auto [ impl(in? path) ]? | [ impl(in? path) ]?) trait` item? + /// Is this an `[impl(in? path)]? const? unsafe? auto? trait` item? fn check_trait_front_matter(&mut self) -> bool { - // `[ impl(in? path) ]? trait` - if self.is_trait_with_maybe_impl_restriction_in_front(0) { - return true; - } - // `auto [ impl(in? path) ]? trait` - if self.check_keyword(exp!(Auto)) && self.is_trait_with_maybe_impl_restriction_in_front(1) { - return true; - } - // `unsafe auto? [ impl(in? path) ]? trait` - if self.check_keyword(exp!(Unsafe)) - && (self.is_trait_with_maybe_impl_restriction_in_front(1) - || self.is_keyword_ahead(1, &[kw::Auto]) - && self.is_trait_with_maybe_impl_restriction_in_front(2)) - { - return true; - } - // `const` ... - if !self.check_keyword(exp!(Const)) { - return false; - } - // `const [ impl(in? path) ]? trait` - if self.is_trait_with_maybe_impl_restriction_in_front(1) { - return true; - } - // `const (unsafe | auto) [ impl(in? path) ]? trait` - if self.is_keyword_ahead(1, &[kw::Unsafe, kw::Auto]) - && self.is_trait_with_maybe_impl_restriction_in_front(2) - { - return true; + const SUFFIXES: &[&[Symbol]] = &[ + &[kw::Trait], + &[kw::Auto, kw::Trait], + &[kw::Unsafe, kw::Trait], + &[kw::Unsafe, kw::Auto, kw::Trait], + &[kw::Const, kw::Trait], + &[kw::Const, kw::Auto, kw::Trait], + &[kw::Const, kw::Unsafe, kw::Trait], + &[kw::Const, kw::Unsafe, kw::Auto, kw::Trait], + ]; + // `impl(` + if self.check_keyword(exp!(Impl)) && self.look_ahead(1, |t| t == &token::OpenParen) { + // Since the `path` in `impl(in? path)` can be arbitrarily long, + // we treat `(in? path)` as a `TokenTree::Delimited`, + // so we look ahead over token trees rather than tokens. + SUFFIXES.iter().any(|suffix| { + suffix.iter().enumerate().all(|(i, kw)| { + self.tree_look_ahead(i + 2, |t| { + if let TokenTree::Token(token, _) = t { + token.is_keyword(*kw) + } else { + false + } + }) + .unwrap_or(false) + }) + }) + } else { + SUFFIXES.iter().any(|suffix| { + suffix.iter().enumerate().all(|(i, kw)| { + // We use `check_keyword` for the first token to include it in the expected tokens. + if i == 0 { + match *kw { + kw::Const => self.check_keyword(exp!(Const)), + kw::Unsafe => self.check_keyword(exp!(Unsafe)), + kw::Auto => self.check_keyword(exp!(Auto)), + kw::Trait => self.check_keyword(exp!(Trait)), + _ => unreachable!(), + } + } else { + self.is_keyword_ahead(i, &[*kw]) + } + }) + }) } - // `const unsafe auto [ impl(in? path) ]? trait` - self.is_keyword_ahead(1, &[kw::Unsafe]) - && self.is_keyword_ahead(2, &[kw::Auto]) - && self.is_trait_with_maybe_impl_restriction_in_front(3) } - /// Parses `const? unsafe? auto? [impl(in? path)]? trait Foo { ... }` or `trait Foo = Bar;`. - /// - /// FIXME(restrictions): The current keyword order follows the grammar specified in RFC 3323. - /// However, whether the restriction should be grouped closer to the visibility modifier - /// (e.g., `pub impl(crate) const unsafe auto trait`) remains an unresolved design question. - /// This ordering must be kept in sync with the logic in `check_trait_front_matter`. + /// Parses `[impl(in? path)]? const? unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`. fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> { + let impl_restriction = self.parse_impl_restriction()?; let constness = self.parse_constness(Case::Sensitive); if let Const::Yes(span) = constness { self.psess.gated_spans.gate(sym::const_trait_impl, span); @@ -1139,8 +1117,6 @@ impl<'a> Parser<'a> { IsAuto::No }; - let impl_restriction = self.parse_impl_restriction()?; - self.expect_keyword(exp!(Trait))?; let ident = self.parse_ident()?; let mut generics = self.parse_generics()?; @@ -2966,8 +2942,8 @@ impl<'a> Parser<'a> { && !self.is_unsafe_foreign_mod() // Rule out `async gen {` and `async gen move {` && !self.is_async_gen_block() - // Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl`. - && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait, kw::Impl]) + // Rule out `const unsafe auto` and `const unsafe trait` + && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait]) ) }) // `extern ABI fn` From 5d8a2977b1f07c04ed8d687f8deb0aa46f87e80e Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Sat, 18 Apr 2026 23:41:16 +0900 Subject: [PATCH 2/7] Update `rustfmt` --- src/tools/rustfmt/src/items.rs | 2 +- .../rustfmt/tests/source/impl-restriction.rs | 19 ++++++++++--------- .../rustfmt/tests/target/impl-restriction.rs | 8 ++++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index a4251a9a3bd4e..baa1cd38237bf 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -1169,10 +1169,10 @@ pub(crate) fn format_trait( let header = format!( "{}{}{}{}{}trait ", format_visibility(context, &item.vis), + format_impl_restriction(context, impl_restriction), format_constness(constness), format_safety(safety), format_auto(is_auto), - format_impl_restriction(context, impl_restriction), ); result.push_str(&header); diff --git a/src/tools/rustfmt/tests/source/impl-restriction.rs b/src/tools/rustfmt/tests/source/impl-restriction.rs index 4459d9a8ba2b5..3203626eaaae8 100644 --- a/src/tools/rustfmt/tests/source/impl-restriction.rs +++ b/src/tools/rustfmt/tests/source/impl-restriction.rs @@ -18,24 +18,25 @@ bar ) trait Baz {} pub -const impl (self) +const trait QuxConst {} -pub -auto impl( +pub +impl( super -) +) auto trait QuxAuto {} -pub -unsafe impl -(in crate) +pub +impl +(in crate) unsafe trait QuxUnsafe {} -pub const -unsafe impl +pub +impl (in super ::foo) +const unsafe trait QuxConstUnsafe {} diff --git a/src/tools/rustfmt/tests/target/impl-restriction.rs b/src/tools/rustfmt/tests/target/impl-restriction.rs index 4ff617af0f257..f5e1f3b7f6b5f 100644 --- a/src/tools/rustfmt/tests/target/impl-restriction.rs +++ b/src/tools/rustfmt/tests/target/impl-restriction.rs @@ -6,10 +6,10 @@ pub impl(in crate) trait Bar {} pub impl(in foo::bar) trait Baz {} -pub const impl(self) trait QuxConst {} +pub impl(self) const trait QuxConst {} -pub auto impl(super) trait QuxAuto {} +pub impl(super) auto trait QuxAuto {} -pub unsafe impl(in crate) trait QuxUnsafe {} +pub impl(in crate) unsafe trait QuxUnsafe {} -pub const unsafe impl(in super::foo) trait QuxConstUnsafe {} +pub impl(in super::foo) const unsafe trait QuxConstUnsafe {} From a0b8e894564662a0eeee0d6230a83c82c1ef5da7 Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Sun, 19 Apr 2026 00:01:43 +0900 Subject: [PATCH 3/7] Update AST pretty printing --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_ast_pretty/src/pprust/state/item.rs | 4 ++-- compiler/rustc_parse/src/parser/item.rs | 2 +- src/tools/clippy/clippy_utils/src/ast_utils/mod.rs | 8 ++++---- src/tools/rustfmt/src/items.rs | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index b2c573c23f891..4eff1352d7e66 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -3786,10 +3786,10 @@ pub struct TraitAlias { #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct Trait { + pub impl_restriction: ImplRestriction, pub constness: Const, pub safety: Safety, pub is_auto: IsAuto, - pub impl_restriction: ImplRestriction, pub ident: Ident, pub generics: Generics, #[visitable(extra = BoundKind::SuperTraits)] diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 239daecd3d1fb..6d5d34268ea18 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -543,10 +543,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { }) } ItemKind::Trait(box Trait { + impl_restriction, constness, is_auto, safety, - impl_restriction, ident, generics, bounds, diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index cb9bbf014e013..5154e5dc005cd 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -371,10 +371,10 @@ impl<'a> State<'a> { self.bclose(item.span, empty, cb); } ast::ItemKind::Trait(box ast::Trait { + impl_restriction, constness, safety, is_auto, - impl_restriction, ident, generics, bounds, @@ -382,10 +382,10 @@ impl<'a> State<'a> { }) => { let (cb, ib) = self.head(""); self.print_visibility(&item.vis); + self.print_impl_restriction(impl_restriction); self.print_constness(*constness); self.print_safety(*safety); self.print_is_auto(*is_auto); - self.print_impl_restriction(impl_restriction); self.word_nbsp("trait"); self.print_ident(*ident); self.print_generic_params(&generics.params); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 0be16e35b7b35..e72cf491004e3 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1157,10 +1157,10 @@ impl<'a> Parser<'a> { generics.where_clause = self.parse_where_clause()?; let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?; Ok(ItemKind::Trait(Box::new(Trait { + impl_restriction, constness, is_auto, safety, - impl_restriction, ident, generics, bounds, diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index c96c0649753fd..82142d55e21d8 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -448,30 +448,30 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool { }, ( Trait(box ast::Trait { + impl_restriction: liprt, constness: lc, is_auto: la, safety: lu, - impl_restriction: liprt, ident: li, generics: lg, bounds: lb, items: lis, }), Trait(box ast::Trait { + impl_restriction: riprt, constness: rc, is_auto: ra, safety: ru, - impl_restriction: riprt, ident: ri, generics: rg, bounds: rb, items: ris, }), ) => { - matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No) + eq_impl_restriction(liprt, riprt) + && matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No) && la == ra && matches!(lu, Safety::Default) == matches!(ru, Safety::Default) - && eq_impl_restriction(liprt, riprt) && eq_id(*li, *ri) && eq_generics(lg, rg) && over(lb, rb, eq_generic_bound) diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index baa1cd38237bf..32f71703e019f 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -1155,10 +1155,10 @@ pub(crate) fn format_trait( offset: Indent, ) -> RewriteResult { let ast::Trait { + ref impl_restriction, constness, is_auto, safety, - ref impl_restriction, ident, ref generics, ref bounds, From 614994fb8bc91593b21bc780adaf892e166841d0 Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Sun, 19 Apr 2026 00:22:40 +0900 Subject: [PATCH 4/7] Update HIR pretty printing --- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_hir/src/hir.rs | 8 ++++---- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir_analysis/src/collect.rs | 4 ++-- compiler/rustc_hir_pretty/src/lib.rs | 4 ++-- compiler/rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_middle/src/ty/trait_def.rs | 6 +++--- .../src/error_reporting/traits/suggestions.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- .../clippy_lints/src/arbitrary_source_item_ordering.rs | 2 +- src/tools/clippy/clippy_lints/src/doc/mod.rs | 2 +- src/tools/clippy/clippy_utils/src/check_proc_macro.rs | 4 ++-- 12 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 6d5d34268ea18..8262681517ff4 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -573,10 +573,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { }, ); hir::ItemKind::Trait( + impl_restriction, constness, *is_auto, safety, - impl_restriction, ident, generics, bounds, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c662b88209bd5..4398db10239f9 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4327,17 +4327,17 @@ impl<'hir> Item<'hir> { expect_trait, ( + &'hir ImplRestriction<'hir>, Constness, IsAuto, Safety, - &'hir ImplRestriction<'hir>, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, &'hir [TraitItemId] ), - ItemKind::Trait(constness, is_auto, safety, impl_restriction, ident, generics, bounds, items), - (*constness, *is_auto, *safety, impl_restriction, *ident, generics, bounds, items); + ItemKind::Trait(impl_restriction, constness, is_auto, safety, ident, generics, bounds, items), + (impl_restriction, *constness, *is_auto, *safety, *ident, generics, bounds, items); expect_trait_alias, (Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>), ItemKind::TraitAlias(constness, ident, generics, bounds), (*constness, *ident, generics, bounds); @@ -4529,10 +4529,10 @@ pub enum ItemKind<'hir> { Union(Ident, &'hir Generics<'hir>, VariantData<'hir>), /// A trait definition. Trait( + &'hir ImplRestriction<'hir>, Constness, IsAuto, Safety, - &'hir ImplRestriction<'hir>, Ident, &'hir Generics<'hir>, GenericBounds<'hir>, diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 99511189e9283..7c7c9939479fe 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -619,10 +619,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_variant_data(struct_definition)); } ItemKind::Trait( + ref impl_restriction, _constness, _is_auto, _safety, - ref impl_restriction, ident, ref generics, bounds, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 91f6c1a08f152..f6a18c33b9507 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -894,7 +894,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { let item = tcx.hir_expect_item(def_id); let (constness, is_alias, is_auto, safety, impl_restriction) = match item.kind { - hir::ItemKind::Trait(constness, is_auto, safety, impl_restriction, ..) => ( + hir::ItemKind::Trait(impl_restriction, constness, is_auto, safety, ..) => ( constness, false, is_auto == hir::IsAuto::Yes, @@ -958,9 +958,9 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { ty::TraitDef { def_id: def_id.to_def_id(), + impl_restriction, safety, constness, - impl_restriction, paren_sugar, has_auto_impl: is_auto, is_marker, diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 6f64d07b01d66..a387db74c8760 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -758,20 +758,20 @@ impl<'a> State<'a> { self.bclose(item.span, cb); } hir::ItemKind::Trait( + impl_restriction, constness, is_auto, safety, - impl_restriction, ident, generics, bounds, trait_items, ) => { let (cb, ib) = self.head(""); + self.print_impl_restriction(impl_restriction); self.print_constness(constness); self.print_is_auto(is_auto); self.print_safety(safety); - self.print_impl_restriction(impl_restriction); self.word_nbsp("trait"); self.print_ident(ident); self.print_generic_params(generics.params); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 3fcc3f03f7aa5..1af34fcc73a16 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1886,7 +1886,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { entry.1.insert((self_ty.span, String::new())); } Some(Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, rustc_ast::ast::IsAuto::Yes, ..), + kind: hir::ItemKind::Trait(_, _, rustc_ast::ast::IsAuto::Yes, ..), span: item_span, .. })) => { diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index af5d81a108ba7..4ebd6f860ee90 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -20,14 +20,14 @@ use crate::ty::{Ident, Ty, TyCtxt}; pub struct TraitDef { pub def_id: DefId, + /// Restrictions on trait implementations. + pub impl_restriction: ImplRestrictionKind, + pub safety: hir::Safety, /// Whether this trait is `const`. pub constness: hir::Constness, - /// Restrictions on trait implementations. - pub impl_restriction: ImplRestrictionKind, - /// If `true`, then this trait had the `#[rustc_paren_sugar]` /// attribute, indicating that it should be used with `Foo()` /// sugar. This is a temporary thing -- eventually any trait will diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 9a9238f5c7994..64c1148b359a8 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3888,7 +3888,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let mut is_auto_trait = false; match tcx.hir_get_if_local(data.impl_or_alias_def_id) { Some(Node::Item(hir::Item { - kind: hir::ItemKind::Trait(_, is_auto, _, _, ident, _, _, _), + kind: hir::ItemKind::Trait(_, _, is_auto, _, ident, _, _, _), .. })) => { // FIXME: we should do something else so that it works even on crate foreign diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 501420bdc88fc..d4df6978a4e21 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2916,7 +2916,7 @@ fn clean_maybe_renamed_item<'tcx>( clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx) } // FIXME: rustdoc will need to handle `impl` restrictions at some point - ItemKind::Trait(_, _, _, _impl_restriction, _, generics, bounds, item_ids) => { + ItemKind::Trait(_impl_restriction, _, _, _, _, generics, bounds, item_ids) => { let items = item_ids .iter() .map(|&ti| clean_trait_item(cx.tcx.hir_trait_item(ti), cx)) diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs index dae0c8439ea82..4a6c024cac9a6 100644 --- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs +++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs @@ -307,10 +307,10 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering { } }, ItemKind::Trait( + _impl_restriction, _constness, is_auto, _safety, - _impl_restriction, _ident, _generics, _generic_bounds, diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs index a94133376cbfb..81812880a743a 100644 --- a/src/tools/clippy/clippy_lints/src/doc/mod.rs +++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs @@ -769,7 +769,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation { { missing_headers::check(cx, item.owner_id, sig, headers, Some(body), self.check_private_items); }, - ItemKind::Trait(_, _, unsafety, ..) => match (headers.safety, unsafety) { + ItemKind::Trait(_, _, _, unsafety, ..) => match (headers.safety, unsafety) { (false, Safety::Unsafe) => span_lint( cx, MISSING_SAFETY_DOC, diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index 601cf564062bb..44b9084cd4f69 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -265,14 +265,14 @@ 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 { of_trait: Some(TraitImplHeader { 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("}")), ItemKind::Mod(..) => (Pat::Str("mod"), Pat::Str("")), From 0e6efe57d7081c1ceb3f55b5b8853ea5a8b6d1d3 Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Sun, 19 Apr 2026 01:16:38 +0900 Subject: [PATCH 5/7] Update UI tests --- .../feature-gate-impl-restriction.rs | 20 +-- ...-gate-impl-restriction.without_gate.stderr | 60 +++---- .../recover-incorrect-impl-restriction.rs | 43 +++-- ...recover-incorrect-impl-restriction.stderr} | 69 ++++---- ...rrect-impl-restriction.without_gate.stderr | 159 ------------------ .../trait-alias-cannot-be-impl-restricted.rs | 27 +-- ...it-alias-cannot-be-impl-restricted.stderr} | 59 +++---- ...not-be-impl-restricted.without_gate.stderr | 145 ---------------- tests/ui/macros/stringify.rs | 52 +++--- 9 files changed, 155 insertions(+), 479 deletions(-) rename tests/ui/impl-restriction/{recover-incorrect-impl-restriction.with_gate.stderr => recover-incorrect-impl-restriction.stderr} (62%) delete mode 100644 tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr rename tests/ui/impl-restriction/{trait-alias-cannot-be-impl-restricted.with_gate.stderr => trait-alias-cannot-be-impl-restricted.stderr} (50%) delete mode 100644 tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr diff --git a/tests/ui/impl-restriction/feature-gate-impl-restriction.rs b/tests/ui/impl-restriction/feature-gate-impl-restriction.rs index 95a050fe444ab..737af7488c44a 100644 --- a/tests/ui/impl-restriction/feature-gate-impl-restriction.rs +++ b/tests/ui/impl-restriction/feature-gate-impl-restriction.rs @@ -11,14 +11,14 @@ pub impl(in crate) trait BarInCrate {} //[without_gate]~ ERROR `impl` restrictio mod foo { pub impl(in crate::foo) trait Baz {} //[without_gate]~ ERROR `impl` restrictions are experimental - pub unsafe impl(super) trait BazUnsafeSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental - pub auto impl(self) trait BazAutoSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental - pub const impl(in self) trait BazConst {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(super) unsafe trait BazUnsafeSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(self) auto trait BazAutoSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(in self) const trait BazConst {} //[without_gate]~ ERROR `impl` restrictions are experimental mod foo_inner { pub impl(in crate::foo::foo_inner) trait Qux {} //[without_gate]~ ERROR `impl` restrictions are experimental - pub unsafe auto impl(in crate::foo::foo_inner) trait QuxAutoUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental - pub const unsafe impl(in crate::foo::foo_inner) trait QuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(in crate::foo::foo_inner) unsafe auto trait QuxAutoUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(in crate::foo::foo_inner) const unsafe trait QuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental } #[cfg(false)] @@ -26,17 +26,17 @@ mod foo { #[cfg(false)] pub impl(in crate) trait BarInCrate {} //[without_gate]~ ERROR `impl` restrictions are experimental #[cfg(false)] - pub unsafe impl(self) trait BazUnsafeSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(self) unsafe trait BazUnsafeSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental #[cfg(false)] - pub auto impl(in super) trait BazAutoSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(in super) auto trait BazAutoSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental #[cfg(false)] - pub const impl(super) trait BazConstSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(super) const trait BazConstSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental #[cfg(false)] mod cfged_out_foo { pub impl(in crate::foo::cfged_out_foo) trait CfgedOutQux {} //[without_gate]~ ERROR `impl` restrictions are experimental - pub unsafe auto impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxUnsafeAuto {} //[without_gate]~ ERROR `impl` restrictions are experimental - pub const unsafe impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(in crate::foo::cfged_out_foo) unsafe auto trait CfgedOutQuxUnsafeAuto {} //[without_gate]~ ERROR `impl` restrictions are experimental + pub impl(in crate::foo::cfged_out_foo) const unsafe trait CfgedOutQuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental } // auto traits cannot be const, so we do not include these combinations in the test. diff --git a/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr b/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr index 4f99d962d4bb7..d1f27350d1ba7 100644 --- a/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr +++ b/tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr @@ -29,30 +29,30 @@ LL | pub impl(in crate::foo) trait Baz {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:14:16 + --> $DIR/feature-gate-impl-restriction.rs:14:9 | -LL | pub unsafe impl(super) trait BazUnsafeSuper {} - | ^^^^^^^^^^^ +LL | pub impl(super) unsafe trait BazUnsafeSuper {} + | ^^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:15:14 + --> $DIR/feature-gate-impl-restriction.rs:15:9 | -LL | pub auto impl(self) trait BazAutoSelf {} - | ^^^^^^^^^^ +LL | pub impl(self) auto trait BazAutoSelf {} + | ^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:16:15 + --> $DIR/feature-gate-impl-restriction.rs:16:9 | -LL | pub const impl(in self) trait BazConst {} - | ^^^^^^^^^^^^^ +LL | pub impl(in self) const trait BazConst {} + | ^^^^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable @@ -69,20 +69,20 @@ LL | pub impl(in crate::foo::foo_inner) trait Qux {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:20:25 + --> $DIR/feature-gate-impl-restriction.rs:20:13 | -LL | ... pub unsafe auto impl(in crate::foo::foo_inner) trait QuxAutoUnsafe {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... pub impl(in crate::foo::foo_inner) unsafe auto trait QuxAutoUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:21:26 + --> $DIR/feature-gate-impl-restriction.rs:21:13 | -LL | ... pub const unsafe impl(in crate::foo::foo_inner) trait QuxConstUnsafe {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... pub impl(in crate::foo::foo_inner) const unsafe trait QuxConstUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable @@ -109,30 +109,30 @@ LL | pub impl(in crate) trait BarInCrate {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:29:16 + --> $DIR/feature-gate-impl-restriction.rs:29:9 | -LL | pub unsafe impl(self) trait BazUnsafeSelf {} - | ^^^^^^^^^^ +LL | pub impl(self) unsafe trait BazUnsafeSelf {} + | ^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:31:14 + --> $DIR/feature-gate-impl-restriction.rs:31:9 | -LL | pub auto impl(in super) trait BazAutoSuper {} - | ^^^^^^^^^^^^^^ +LL | pub impl(in super) auto trait BazAutoSuper {} + | ^^^^^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:33:15 + --> $DIR/feature-gate-impl-restriction.rs:33:9 | -LL | pub const impl(super) trait BazConstSuper {} - | ^^^^^^^^^^^ +LL | pub impl(super) const trait BazConstSuper {} + | ^^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable @@ -149,20 +149,20 @@ LL | pub impl(in crate::foo::cfged_out_foo) trait CfgedOutQux {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:38:25 + --> $DIR/feature-gate-impl-restriction.rs:38:13 | -LL | ... pub unsafe auto impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxUnsafeAuto {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... pub impl(in crate::foo::cfged_out_foo) unsafe auto trait CfgedOutQuxUnsafeAuto {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: `impl` restrictions are experimental - --> $DIR/feature-gate-impl-restriction.rs:39:26 + --> $DIR/feature-gate-impl-restriction.rs:39:13 | -LL | ... pub const unsafe impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxConstUnsafe {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ... pub impl(in crate::foo::cfged_out_foo) const unsafe trait CfgedOutQuxConstUnsafe {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: see issue #105077 for more information = help: add `#![feature(impl_restriction)]` to the crate attributes to enable diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs index dc47eba2b3c63..a11c7659ba780 100644 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs @@ -1,21 +1,30 @@ -//@ compile-flags: --crate-type=lib -//@ revisions: with_gate without_gate -#![warn(incomplete_features)] -#![cfg_attr(with_gate, feature(impl_restriction))] -//[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes -#![feature(auto_traits, const_trait_impl)] +#![feature(impl_restriction, auto_traits, const_trait_impl)] +#![expect(incomplete_features)] mod foo { pub impl(crate::foo) trait Baz {} //~ ERROR incorrect `impl` restriction - //[without_gate]~^ ERROR `impl` restrictions are experimental - pub unsafe impl(crate::foo) trait BazUnsafe {} //~ ERROR incorrect `impl` restriction - //[without_gate]~^ ERROR `impl` restrictions are experimental - pub auto impl(crate::foo) trait BazAuto {} //~ ERROR incorrect `impl` restriction - //[without_gate]~^ ERROR `impl` restrictions are experimental - pub const impl(crate::foo) trait BazConst {} //~ ERROR incorrect `impl` restriction - //[without_gate]~^ ERROR `impl` restrictions are experimental - pub const unsafe impl(crate::foo) trait BazConstUnsafe {} //~ ERROR incorrect `impl` restriction - //[without_gate]~^ ERROR `impl` restrictions are experimental - pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} //~ ERROR incorrect `impl` restriction - //[without_gate]~^ ERROR `impl` restrictions are experimental + pub impl(crate::foo) unsafe trait BazUnsafe {} //~ ERROR incorrect `impl` restriction + pub impl(crate::foo) auto trait BazAuto {} //~ ERROR incorrect `impl` restriction + pub impl(crate::foo) const trait BazConst {} //~ ERROR incorrect `impl` restriction + pub impl(crate::foo) const unsafe trait BazConstUnsafe {} //~ ERROR incorrect `impl` restriction + pub impl(crate::foo) unsafe auto trait BazUnsafeAuto {} //~ ERROR incorrect `impl` restriction + + // FIXME: The positioning of `impl(..)` may be confusing. + // When users get the keyword order wrong, the compiler currently emits + // a generic "unexpected token" error, which is not very helpful. + // In the future, we could improve diagnostics by detecting misordered + // keywords and suggesting the correct order. + pub unsafe impl(crate::foo) trait BadOrder1 {} //~ ERROR expected one of `for`, `where`, or `{`, found keyword `trait` + + // FIXME: The following cases are not checked for now, + // as the compiler aborts due to the previous syntax error in `BadOrder1`. + // In the future, we could recover from such errors and continue compilation. + pub auto impl(crate::foo) trait BadOrder2 {} + pub const impl(crate::foo) trait BadOrder3 {} + pub unsafe auto impl(crate::foo) trait BadOrder4 {} + pub const unsafe impl(crate::foo) trait BadOrder5 {} + pub unsafe impl(crate::foo) auto trait BadOrder6 {} + pub const impl(crate::foo) unsafe trait BadOrder7 {} } + +fn main() {} diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.stderr similarity index 62% rename from tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr rename to tests/ui/impl-restriction/recover-incorrect-impl-restriction.stderr index 834cc99f07553..23aff244bb71b 100644 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.with_gate.stderr +++ b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.stderr @@ -1,5 +1,5 @@ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:9:14 + --> $DIR/recover-incorrect-impl-restriction.rs:5:14 | LL | pub impl(crate::foo) trait Baz {} | ^^^^^^^^^^ @@ -15,10 +15,10 @@ LL | pub impl(in crate::foo) trait Baz {} | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:11:21 + --> $DIR/recover-incorrect-impl-restriction.rs:6:14 | -LL | pub unsafe impl(crate::foo) trait BazUnsafe {} - | ^^^^^^^^^^ +LL | pub impl(crate::foo) unsafe trait BazUnsafe {} + | ^^^^^^^^^^ | = help: some possible `impl` restrictions are: `impl(crate)`: can only be implemented in the current crate @@ -27,14 +27,14 @@ LL | pub unsafe impl(crate::foo) trait BazUnsafe {} `impl(in path::to::module)`: can only be implemented in the specified path help: help: use `in` to restrict implementations to the path `crate::foo` | -LL | pub unsafe impl(in crate::foo) trait BazUnsafe {} - | ++ +LL | pub impl(in crate::foo) unsafe trait BazUnsafe {} + | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:13:19 + --> $DIR/recover-incorrect-impl-restriction.rs:7:14 | -LL | pub auto impl(crate::foo) trait BazAuto {} - | ^^^^^^^^^^ +LL | pub impl(crate::foo) auto trait BazAuto {} + | ^^^^^^^^^^ | = help: some possible `impl` restrictions are: `impl(crate)`: can only be implemented in the current crate @@ -43,14 +43,14 @@ LL | pub auto impl(crate::foo) trait BazAuto {} `impl(in path::to::module)`: can only be implemented in the specified path help: help: use `in` to restrict implementations to the path `crate::foo` | -LL | pub auto impl(in crate::foo) trait BazAuto {} - | ++ +LL | pub impl(in crate::foo) auto trait BazAuto {} + | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:15:20 + --> $DIR/recover-incorrect-impl-restriction.rs:8:14 | -LL | pub const impl(crate::foo) trait BazConst {} - | ^^^^^^^^^^ +LL | pub impl(crate::foo) const trait BazConst {} + | ^^^^^^^^^^ | = help: some possible `impl` restrictions are: `impl(crate)`: can only be implemented in the current crate @@ -59,14 +59,14 @@ LL | pub const impl(crate::foo) trait BazConst {} `impl(in path::to::module)`: can only be implemented in the specified path help: help: use `in` to restrict implementations to the path `crate::foo` | -LL | pub const impl(in crate::foo) trait BazConst {} - | ++ +LL | pub impl(in crate::foo) const trait BazConst {} + | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:17:27 + --> $DIR/recover-incorrect-impl-restriction.rs:9:14 | -LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} - | ^^^^^^^^^^ +LL | pub impl(crate::foo) const unsafe trait BazConstUnsafe {} + | ^^^^^^^^^^ | = help: some possible `impl` restrictions are: `impl(crate)`: can only be implemented in the current crate @@ -75,14 +75,14 @@ LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} `impl(in path::to::module)`: can only be implemented in the specified path help: help: use `in` to restrict implementations to the path `crate::foo` | -LL | pub const unsafe impl(in crate::foo) trait BazConstUnsafe {} - | ++ +LL | pub impl(in crate::foo) const unsafe trait BazConstUnsafe {} + | ++ error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:19:26 + --> $DIR/recover-incorrect-impl-restriction.rs:10:14 | -LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} - | ^^^^^^^^^^ +LL | pub impl(crate::foo) unsafe auto trait BazUnsafeAuto {} + | ^^^^^^^^^^ | = help: some possible `impl` restrictions are: `impl(crate)`: can only be implemented in the current crate @@ -91,21 +91,14 @@ LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} `impl(in path::to::module)`: can only be implemented in the specified path help: help: use `in` to restrict implementations to the path `crate::foo` | -LL | pub unsafe auto impl(in crate::foo) trait BazUnsafeAuto {} - | ++ +LL | pub impl(in crate::foo) unsafe auto trait BazUnsafeAuto {} + | ++ -warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/recover-incorrect-impl-restriction.rs:4:32 - | -LL | #![cfg_attr(with_gate, feature(impl_restriction))] - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information -note: the lint level is defined here - --> $DIR/recover-incorrect-impl-restriction.rs:3:9 +error: expected one of `for`, `where`, or `{`, found keyword `trait` + --> $DIR/recover-incorrect-impl-restriction.rs:17:33 | -LL | #![warn(incomplete_features)] - | ^^^^^^^^^^^^^^^^^^^ +LL | pub unsafe impl(crate::foo) trait BadOrder1 {} + | ^^^^^ expected one of `for`, `where`, or `{` -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 7 previous errors diff --git a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr b/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr deleted file mode 100644 index 223a7cd47cfb4..0000000000000 --- a/tests/ui/impl-restriction/recover-incorrect-impl-restriction.without_gate.stderr +++ /dev/null @@ -1,159 +0,0 @@ -error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:9:14 - | -LL | pub impl(crate::foo) trait Baz {} - | ^^^^^^^^^^ - | - = help: some possible `impl` restrictions are: - `impl(crate)`: can only be implemented in the current crate - `impl(super)`: can only be implemented in the parent module - `impl(self)`: can only be implemented in current module - `impl(in path::to::module)`: can only be implemented in the specified path -help: help: use `in` to restrict implementations to the path `crate::foo` - | -LL | pub impl(in crate::foo) trait Baz {} - | ++ - -error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:11:21 - | -LL | pub unsafe impl(crate::foo) trait BazUnsafe {} - | ^^^^^^^^^^ - | - = help: some possible `impl` restrictions are: - `impl(crate)`: can only be implemented in the current crate - `impl(super)`: can only be implemented in the parent module - `impl(self)`: can only be implemented in current module - `impl(in path::to::module)`: can only be implemented in the specified path -help: help: use `in` to restrict implementations to the path `crate::foo` - | -LL | pub unsafe impl(in crate::foo) trait BazUnsafe {} - | ++ - -error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:13:19 - | -LL | pub auto impl(crate::foo) trait BazAuto {} - | ^^^^^^^^^^ - | - = help: some possible `impl` restrictions are: - `impl(crate)`: can only be implemented in the current crate - `impl(super)`: can only be implemented in the parent module - `impl(self)`: can only be implemented in current module - `impl(in path::to::module)`: can only be implemented in the specified path -help: help: use `in` to restrict implementations to the path `crate::foo` - | -LL | pub auto impl(in crate::foo) trait BazAuto {} - | ++ - -error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:15:20 - | -LL | pub const impl(crate::foo) trait BazConst {} - | ^^^^^^^^^^ - | - = help: some possible `impl` restrictions are: - `impl(crate)`: can only be implemented in the current crate - `impl(super)`: can only be implemented in the parent module - `impl(self)`: can only be implemented in current module - `impl(in path::to::module)`: can only be implemented in the specified path -help: help: use `in` to restrict implementations to the path `crate::foo` - | -LL | pub const impl(in crate::foo) trait BazConst {} - | ++ - -error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:17:27 - | -LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} - | ^^^^^^^^^^ - | - = help: some possible `impl` restrictions are: - `impl(crate)`: can only be implemented in the current crate - `impl(super)`: can only be implemented in the parent module - `impl(self)`: can only be implemented in current module - `impl(in path::to::module)`: can only be implemented in the specified path -help: help: use `in` to restrict implementations to the path `crate::foo` - | -LL | pub const unsafe impl(in crate::foo) trait BazConstUnsafe {} - | ++ - -error: incorrect `impl` restriction - --> $DIR/recover-incorrect-impl-restriction.rs:19:26 - | -LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} - | ^^^^^^^^^^ - | - = help: some possible `impl` restrictions are: - `impl(crate)`: can only be implemented in the current crate - `impl(super)`: can only be implemented in the parent module - `impl(self)`: can only be implemented in current module - `impl(in path::to::module)`: can only be implemented in the specified path -help: help: use `in` to restrict implementations to the path `crate::foo` - | -LL | pub unsafe auto impl(in crate::foo) trait BazUnsafeAuto {} - | ++ - -error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:9:9 - | -LL | pub impl(crate::foo) trait Baz {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:11:16 - | -LL | pub unsafe impl(crate::foo) trait BazUnsafe {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:13:14 - | -LL | pub auto impl(crate::foo) trait BazAuto {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:15:15 - | -LL | pub const impl(crate::foo) trait BazConst {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:17:22 - | -LL | pub const unsafe impl(crate::foo) trait BazConstUnsafe {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/recover-incorrect-impl-restriction.rs:19:21 - | -LL | pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 12 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs index ce36a49b145b0..d191950ec40ef 100644 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.rs @@ -1,29 +1,20 @@ -//@ compile-flags: --crate-type=lib -//@ revisions: with_gate without_gate -#![warn(incomplete_features)] -#![cfg_attr(with_gate, feature(impl_restriction))] -//[with_gate]~^ WARN the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes -#![feature(auto_traits, const_trait_impl, trait_alias)] +#![feature(impl_restriction, auto_traits, const_trait_impl, trait_alias)] +#![expect(incomplete_features)] impl(crate) trait Alias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted -//[without_gate]~^ ERROR `impl` restrictions are experimental -auto impl(in crate) trait AutoAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +impl(in crate) auto trait AutoAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted //~^ ERROR trait aliases cannot be `auto` -//[without_gate]~| ERROR `impl` restrictions are experimental -unsafe impl(self) trait UnsafeAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted +impl(self) unsafe trait UnsafeAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted //~^ ERROR trait aliases cannot be `unsafe` -//[without_gate]~| ERROR `impl` restrictions are experimental -const impl(in self) trait ConstAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted -//[without_gate]~^ ERROR `impl` restrictions are experimental +impl(in self) const trait ConstAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted mod foo { impl(super) trait InnerAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted - //[without_gate]~^ ERROR `impl` restrictions are experimental - const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted + impl(in crate::foo) const unsafe trait InnerConstUnsafeAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted //~^ ERROR trait aliases cannot be `unsafe` - //[without_gate]~| ERROR `impl` restrictions are experimental - unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted + impl(in crate::foo) unsafe auto trait InnerUnsafeAutoAlias = Copy; //~ ERROR trait aliases cannot be `impl`-restricted //~^ ERROR trait aliases cannot be `auto` //~^^ ERROR trait aliases cannot be `unsafe` - //[without_gate]~| ERROR `impl` restrictions are experimental } + +fn main() {} diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.stderr similarity index 50% rename from tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr rename to tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.stderr index 7be030052df50..def89574b041d 100644 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.with_gate.stderr +++ b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.stderr @@ -1,87 +1,74 @@ error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:4:1 | LL | impl(crate) trait Alias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:5:1 | -LL | auto impl(in crate) trait AutoAlias = Copy; +LL | impl(in crate) auto trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:5:1 | -LL | auto impl(in crate) trait AutoAlias = Copy; +LL | impl(in crate) auto trait AutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 | -LL | unsafe impl(self) trait UnsafeAlias = Copy; +LL | impl(self) unsafe trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:7:1 | -LL | unsafe impl(self) trait UnsafeAlias = Copy; +LL | impl(self) unsafe trait UnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:1 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:9:1 | -LL | const impl(in self) trait ConstAlias = Copy; +LL | impl(in self) const trait ConstAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:12:5 | LL | impl(super) trait InnerAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:5 | -LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; +LL | impl(in crate::foo) const unsafe trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:5 | -LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; +LL | impl(in crate::foo) const unsafe trait InnerConstUnsafeAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:5 | -LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; +LL | impl(in crate::foo) unsafe auto trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:5 | -LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; +LL | impl(in crate::foo) unsafe auto trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 + --> $DIR/trait-alias-cannot-be-impl-restricted.rs:15:5 | -LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; +LL | impl(in crate::foo) unsafe auto trait InnerUnsafeAutoAlias = Copy; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted -warning: the feature `impl_restriction` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:4:32 - | -LL | #![cfg_attr(with_gate, feature(impl_restriction))] - | ^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information -note: the lint level is defined here - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:3:9 - | -LL | #![warn(incomplete_features)] - | ^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 12 previous errors; 1 warning emitted +error: aborting due to 12 previous errors diff --git a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr b/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr deleted file mode 100644 index c99bfce5da2c5..0000000000000 --- a/tests/ui/impl-restriction/trait-alias-cannot-be-impl-restricted.without_gate.stderr +++ /dev/null @@ -1,145 +0,0 @@ -error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 - | -LL | impl(crate) trait Alias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted - -error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 - | -LL | auto impl(in crate) trait AutoAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` - -error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:1 - | -LL | auto impl(in crate) trait AutoAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted - -error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 - | -LL | unsafe impl(self) trait UnsafeAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` - -error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:1 - | -LL | unsafe impl(self) trait UnsafeAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted - -error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:1 - | -LL | const impl(in self) trait ConstAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted - -error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 - | -LL | impl(super) trait InnerAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted - -error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 - | -LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` - -error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:5 - | -LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted - -error: trait aliases cannot be `auto` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 - | -LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `auto` - -error: trait aliases cannot be `unsafe` - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 - | -LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `unsafe` - -error: trait aliases cannot be `impl`-restricted - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:5 - | -LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait aliases cannot be `impl`-restricted - -error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:8:1 - | -LL | impl(crate) trait Alias = Copy; - | ^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:10:6 - | -LL | auto impl(in crate) trait AutoAlias = Copy; - | ^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:13:8 - | -LL | unsafe impl(self) trait UnsafeAlias = Copy; - | ^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:16:7 - | -LL | const impl(in self) trait ConstAlias = Copy; - | ^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:20:5 - | -LL | impl(super) trait InnerAlias = Copy; - | ^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:22:18 - | -LL | const unsafe impl(in crate::foo) trait InnerConstUnsafeAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error[E0658]: `impl` restrictions are experimental - --> $DIR/trait-alias-cannot-be-impl-restricted.rs:25:17 - | -LL | unsafe auto impl(in crate::foo) trait InnerUnsafeAutoAlias = Copy; - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #105077 for more information - = help: add `#![feature(impl_restriction)]` to the crate attributes to enable - = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date - -error: aborting due to 19 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 46f50593c4e95..b48b037b22949 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -864,56 +864,56 @@ fn test_impl_restriction() { ); assert_eq!( - stringify!(pub auto impl(crate) trait Foo {}), - "pub auto impl(crate) trait Foo {}" + stringify!(pub impl(crate) auto trait Foo {}), + "pub impl(crate) auto trait Foo {}" ); assert_eq!( - stringify!(pub auto impl(in crate::path::to) trait Foo {}), - "pub auto impl(in crate::path::to) trait Foo {}" + stringify!(pub impl(in crate::path::to) auto trait Foo {}), + "pub impl(in crate::path::to) auto trait Foo {}" ); assert_eq!( - stringify!(pub unsafe impl(crate) trait Foo {}), - "pub unsafe impl(crate) trait Foo {}" + stringify!(pub impl(crate) unsafe trait Foo {}), + "pub impl(crate) unsafe trait Foo {}" ); assert_eq!( - stringify!(pub unsafe impl(in crate::path::to) trait Foo {}), - "pub unsafe impl(in crate::path::to) trait Foo {}" + stringify!(pub impl(in crate::path::to) unsafe trait Foo {}), + "pub impl(in crate::path::to) unsafe trait Foo {}" ); assert_eq!( - stringify!(pub const impl(crate) trait Foo {}), - "pub const impl(crate) trait Foo {}" + stringify!(pub impl(crate) const trait Foo {}), + "pub impl(crate) const trait Foo {}" ); assert_eq!( - stringify!(pub const impl(in crate::path::to) trait Foo {}), - "pub const impl(in crate::path::to) trait Foo {}" + stringify!(pub impl(in crate::path::to) const trait Foo {}), + "pub impl(in crate::path::to) const trait Foo {}" ); assert_eq!( - stringify!(pub unsafe auto impl(crate) trait Foo {}), - "pub unsafe auto impl(crate) trait Foo {}" + stringify!(pub impl(crate) unsafe auto trait Foo {}), + "pub impl(crate) unsafe auto trait Foo {}" ); assert_eq!( - stringify!(pub unsafe auto impl(in crate::path::to) trait Foo {}), - "pub unsafe auto impl(in crate::path::to) trait Foo {}" + stringify!(pub impl(in crate::path::to) unsafe auto trait Foo {}), + "pub impl(in crate::path::to) unsafe auto trait Foo {}" ); assert_eq!( - stringify!(pub const auto impl(crate) trait Foo {}), - "pub const auto impl(crate) trait Foo {}" + stringify!(pub impl(crate) const auto trait Foo {}), + "pub impl(crate) const auto trait Foo {}" ); assert_eq!( - stringify!(pub const auto impl(in crate::path::to) trait Foo {}), - "pub const auto impl(in crate::path::to) trait Foo {}" + stringify!(pub impl(in crate::path::to) const auto trait Foo {}), + "pub impl(in crate::path::to) const auto trait Foo {}" ); assert_eq!( - stringify!(pub const unsafe impl(crate) trait Foo {}), - "pub const unsafe impl(crate) trait Foo {}" + stringify!(pub impl(crate) const unsafe trait Foo {}), + "pub impl(crate) const unsafe trait Foo {}" ); assert_eq!( - stringify!(pub const unsafe impl(in crate::path::to) trait Foo {}), - "pub const unsafe impl(in crate::path::to) trait Foo {}" + stringify!(pub impl(in crate::path::to) const unsafe trait Foo {}), + "pub impl(in crate::path::to) const unsafe trait Foo {}" ); assert_eq!( - stringify!(pub const unsafe auto impl(crate) trait Foo {}), - "pub const unsafe auto impl(crate) trait Foo {}" + stringify!(pub impl(crate) const unsafe auto trait Foo {}), + "pub impl(crate) const unsafe auto trait Foo {}" ); assert_eq!( stringify!(pub const unsafe auto impl(in crate::path::to) trait Foo {}), From 470e4623db006aeb49504177c51ef04824124319 Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Tue, 21 Apr 2026 22:13:46 +0900 Subject: [PATCH 6/7] Rule out `const unsafe impl` from `FnHeader` to correctly parse `const unsafe trait` implementations. --- compiler/rustc_parse/src/parser/item.rs | 4 ++-- tests/ui/traits/const-traits/const-unsafe-impl.rs | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/const-traits/const-unsafe-impl.rs diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e72cf491004e3..f56e5eda33ee7 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2942,8 +2942,8 @@ impl<'a> Parser<'a> { && !self.is_unsafe_foreign_mod() // Rule out `async gen {` and `async gen move {` && !self.is_async_gen_block() - // Rule out `const unsafe auto` and `const unsafe trait` - && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait]) + // Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl` + && !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait, kw::Impl]) ) }) // `extern ABI fn` diff --git a/tests/ui/traits/const-traits/const-unsafe-impl.rs b/tests/ui/traits/const-traits/const-unsafe-impl.rs new file mode 100644 index 0000000000000..f6aeb22309b0d --- /dev/null +++ b/tests/ui/traits/const-traits/const-unsafe-impl.rs @@ -0,0 +1,10 @@ +// Reported in . +//@ check-pass + +#![feature(const_trait_impl)] + +const unsafe impl Trait for () {} + +const unsafe trait Trait {} + +fn main() {} From cbba81e0e212896fdd0c32270b75e82fc0266ade Mon Sep 17 00:00:00 2001 From: CoCo-Japan-pan <115922543+CoCo-Japan-pan@users.noreply.github.com> Date: Tue, 21 Apr 2026 22:55:35 +0900 Subject: [PATCH 7/7] Add early returns in `check_trait_front_matter` --- compiler/rustc_parse/src/parser/item.rs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index f56e5eda33ee7..96bd59e2519e1 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1066,9 +1066,20 @@ impl<'a> Parser<'a> { ]; // `impl(` if self.check_keyword(exp!(Impl)) && self.look_ahead(1, |t| t == &token::OpenParen) { - // Since the `path` in `impl(in? path)` can be arbitrarily long, - // we treat `(in? path)` as a `TokenTree::Delimited`, - // so we look ahead over token trees rather than tokens. + // `impl(in` unambiguously introduces an `impl` restriction + if self.is_keyword_ahead(2, &[kw::In]) { + return true; + } + // `impl(crate | self | super)` + SUFFIX + if self.is_keyword_ahead(2, &[kw::Crate, kw::SelfLower, kw::Super]) + && self.look_ahead(3, |t| t == &token::CloseParen) + && SUFFIXES.iter().any(|suffix| { + suffix.iter().enumerate().all(|(i, kw)| self.is_keyword_ahead(i + 4, &[*kw])) + }) + { + return true; + } + // Recover cases like `impl(path::to::module)` + SUFFIX to suggest inserting `in`. SUFFIXES.iter().any(|suffix| { suffix.iter().enumerate().all(|(i, kw)| { self.tree_look_ahead(i + 2, |t| {