Skip to content

Commit abce9f9

Browse files
Rollup merge of #155442 - CoCo-Japan-pan:impl-restriction-reorder, r=Urgau,fmease,jhpratt
Change keyword order for `impl` restrictions Based on #155222, this PR reorders keywords in trait definitions to group restrictions with visibility. It changes the order from `pub(...) const unsafe auto impl(...) trait Foo {...}` to `pub(...) impl(...) const unsafe auto trait Foo {...}`. Tracking issue for restrictions: #105077 r? @Urgau cc @jhpratt
2 parents 0595fcd + cbba81e commit abce9f9

29 files changed

Lines changed: 269 additions & 595 deletions

File tree

compiler/rustc_ast/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3786,10 +3786,10 @@ pub struct TraitAlias {
37863786

37873787
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
37883788
pub struct Trait {
3789+
pub impl_restriction: ImplRestriction,
37893790
pub constness: Const,
37903791
pub safety: Safety,
37913792
pub is_auto: IsAuto,
3792-
pub impl_restriction: ImplRestriction,
37933793
pub ident: Ident,
37943794
pub generics: Generics,
37953795
#[visitable(extra = BoundKind::SuperTraits)]

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,10 +556,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
556556
})
557557
}
558558
ItemKind::Trait(box Trait {
559+
impl_restriction,
559560
constness,
560561
is_auto,
561562
safety,
562-
impl_restriction,
563563
ident,
564564
generics,
565565
bounds,
@@ -586,10 +586,10 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
586586
},
587587
);
588588
hir::ItemKind::Trait(
589+
impl_restriction,
589590
constness,
590591
*is_auto,
591592
safety,
592-
impl_restriction,
593593
ident,
594594
generics,
595595
bounds,

compiler/rustc_ast_pretty/src/pprust/state/item.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,21 +371,21 @@ impl<'a> State<'a> {
371371
self.bclose(item.span, empty, cb);
372372
}
373373
ast::ItemKind::Trait(box ast::Trait {
374+
impl_restriction,
374375
constness,
375376
safety,
376377
is_auto,
377-
impl_restriction,
378378
ident,
379379
generics,
380380
bounds,
381381
items,
382382
}) => {
383383
let (cb, ib) = self.head("");
384384
self.print_visibility(&item.vis);
385+
self.print_impl_restriction(impl_restriction);
385386
self.print_constness(*constness);
386387
self.print_safety(*safety);
387388
self.print_is_auto(*is_auto);
388-
self.print_impl_restriction(impl_restriction);
389389
self.word_nbsp("trait");
390390
self.print_ident(*ident);
391391
self.print_generic_params(&generics.params);

compiler/rustc_hir/src/hir.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4457,17 +4457,17 @@ impl<'hir> Item<'hir> {
44574457

44584458
expect_trait,
44594459
(
4460+
&'hir ImplRestriction<'hir>,
44604461
Constness,
44614462
IsAuto,
44624463
Safety,
4463-
&'hir ImplRestriction<'hir>,
44644464
Ident,
44654465
&'hir Generics<'hir>,
44664466
GenericBounds<'hir>,
44674467
&'hir [TraitItemId]
44684468
),
4469-
ItemKind::Trait(constness, is_auto, safety, impl_restriction, ident, generics, bounds, items),
4470-
(*constness, *is_auto, *safety, impl_restriction, *ident, generics, bounds, items);
4469+
ItemKind::Trait(impl_restriction, constness, is_auto, safety, ident, generics, bounds, items),
4470+
(impl_restriction, *constness, *is_auto, *safety, *ident, generics, bounds, items);
44714471

44724472
expect_trait_alias, (Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
44734473
ItemKind::TraitAlias(constness, ident, generics, bounds), (*constness, *ident, generics, bounds);
@@ -4659,10 +4659,10 @@ pub enum ItemKind<'hir> {
46594659
Union(Ident, &'hir Generics<'hir>, VariantData<'hir>),
46604660
/// A trait definition.
46614661
Trait(
4662+
&'hir ImplRestriction<'hir>,
46624663
Constness,
46634664
IsAuto,
46644665
Safety,
4665-
&'hir ImplRestriction<'hir>,
46664666
Ident,
46674667
&'hir Generics<'hir>,
46684668
GenericBounds<'hir>,

compiler/rustc_hir/src/intravisit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,10 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
619619
try_visit!(visitor.visit_variant_data(struct_definition));
620620
}
621621
ItemKind::Trait(
622+
ref impl_restriction,
622623
_constness,
623624
_is_auto,
624625
_safety,
625-
ref impl_restriction,
626626
ident,
627627
ref generics,
628628
bounds,

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
895895
let item = tcx.hir_expect_item(def_id);
896896

897897
let (constness, is_alias, is_auto, safety, impl_restriction) = match item.kind {
898-
hir::ItemKind::Trait(constness, is_auto, safety, impl_restriction, ..) => (
898+
hir::ItemKind::Trait(impl_restriction, constness, is_auto, safety, ..) => (
899899
constness,
900900
false,
901901
is_auto == hir::IsAuto::Yes,
@@ -959,9 +959,9 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
959959

960960
ty::TraitDef {
961961
def_id: def_id.to_def_id(),
962+
impl_restriction,
962963
safety,
963964
constness,
964-
impl_restriction,
965965
paren_sugar,
966966
has_auto_impl: is_auto,
967967
is_marker,

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,20 +758,20 @@ impl<'a> State<'a> {
758758
self.bclose(item.span, cb);
759759
}
760760
hir::ItemKind::Trait(
761+
impl_restriction,
761762
constness,
762763
is_auto,
763764
safety,
764-
impl_restriction,
765765
ident,
766766
generics,
767767
bounds,
768768
trait_items,
769769
) => {
770770
let (cb, ib) = self.head("");
771+
self.print_impl_restriction(impl_restriction);
771772
self.print_constness(constness);
772773
self.print_is_auto(is_auto);
773774
self.print_safety(safety);
774-
self.print_impl_restriction(impl_restriction);
775775
self.word_nbsp("trait");
776776
self.print_ident(ident);
777777
self.print_generic_params(generics.params);

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1900,7 +1900,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19001900
entry.1.insert((self_ty.span, String::new()));
19011901
}
19021902
Some(Node::Item(hir::Item {
1903-
kind: hir::ItemKind::Trait(_, rustc_ast::ast::IsAuto::Yes, ..),
1903+
kind: hir::ItemKind::Trait(_, _, rustc_ast::ast::IsAuto::Yes, ..),
19041904
span: item_span,
19051905
..
19061906
})) => {

compiler/rustc_middle/src/ty/trait_def.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ use crate::ty::{Ident, Ty, TyCtxt};
2020
pub struct TraitDef {
2121
pub def_id: DefId,
2222

23+
/// Restrictions on trait implementations.
24+
pub impl_restriction: ImplRestrictionKind,
25+
2326
pub safety: hir::Safety,
2427

2528
/// Whether this trait is `const`.
2629
pub constness: hir::Constness,
2730

28-
/// Restrictions on trait implementations.
29-
pub impl_restriction: ImplRestrictionKind,
30-
3131
/// If `true`, then this trait had the `#[rustc_paren_sugar]`
3232
/// attribute, indicating that it should be used with `Foo()`
3333
/// sugar. This is a temporary thing -- eventually any trait will

compiler/rustc_parse/src/parser/item.rs

Lines changed: 60 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,80 +1052,69 @@ impl<'a> Parser<'a> {
10521052
}
10531053
}
10541054

1055-
/// Is there an `[ impl(in? path) ]? trait` item `dist` tokens ahead?
1056-
fn is_trait_with_maybe_impl_restriction_in_front(&self, dist: usize) -> bool {
1057-
// `trait`
1058-
if self.is_keyword_ahead(dist, &[kw::Trait]) {
1059-
return true;
1060-
}
1061-
// `impl(`
1062-
if !self.is_keyword_ahead(dist, &[kw::Impl])
1063-
|| !self.look_ahead(dist + 1, |t| t == &token::OpenParen)
1064-
{
1065-
return false;
1066-
}
1067-
// `crate | super | self) trait`
1068-
if self.is_keyword_ahead(dist + 2, &[kw::Crate, kw::Super, kw::SelfLower])
1069-
&& self.look_ahead(dist + 3, |t| t == &token::CloseParen)
1070-
&& self.is_keyword_ahead(dist + 4, &[kw::Trait])
1071-
{
1072-
return true;
1073-
}
1074-
// `impl(in? something) trait`
1075-
// We catch cases where the `in` keyword is missing to provide a
1076-
// better error message. This is handled later in
1077-
// `self.recover_incorrect_impl_restriction`.
1078-
self.tree_look_ahead(dist + 2, |t| {
1079-
if let TokenTree::Token(token, _) = t { token.is_keyword(kw::Trait) } else { false }
1080-
})
1081-
.unwrap_or(false)
1082-
}
1083-
1084-
/// Is this an `(const unsafe? auto? [ impl(in? path) ]? | unsafe auto? [ impl(in? path) ]? | auto [ impl(in? path) ]? | [ impl(in? path) ]?) trait` item?
1055+
/// Is this an `[impl(in? path)]? const? unsafe? auto? trait` item?
10851056
fn check_trait_front_matter(&mut self) -> bool {
1086-
// `[ impl(in? path) ]? trait`
1087-
if self.is_trait_with_maybe_impl_restriction_in_front(0) {
1088-
return true;
1089-
}
1090-
// `auto [ impl(in? path) ]? trait`
1091-
if self.check_keyword(exp!(Auto)) && self.is_trait_with_maybe_impl_restriction_in_front(1) {
1092-
return true;
1093-
}
1094-
// `unsafe auto? [ impl(in? path) ]? trait`
1095-
if self.check_keyword(exp!(Unsafe))
1096-
&& (self.is_trait_with_maybe_impl_restriction_in_front(1)
1097-
|| self.is_keyword_ahead(1, &[kw::Auto])
1098-
&& self.is_trait_with_maybe_impl_restriction_in_front(2))
1099-
{
1100-
return true;
1101-
}
1102-
// `const` ...
1103-
if !self.check_keyword(exp!(Const)) {
1104-
return false;
1105-
}
1106-
// `const [ impl(in? path) ]? trait`
1107-
if self.is_trait_with_maybe_impl_restriction_in_front(1) {
1108-
return true;
1109-
}
1110-
// `const (unsafe | auto) [ impl(in? path) ]? trait`
1111-
if self.is_keyword_ahead(1, &[kw::Unsafe, kw::Auto])
1112-
&& self.is_trait_with_maybe_impl_restriction_in_front(2)
1113-
{
1114-
return true;
1057+
const SUFFIXES: &[&[Symbol]] = &[
1058+
&[kw::Trait],
1059+
&[kw::Auto, kw::Trait],
1060+
&[kw::Unsafe, kw::Trait],
1061+
&[kw::Unsafe, kw::Auto, kw::Trait],
1062+
&[kw::Const, kw::Trait],
1063+
&[kw::Const, kw::Auto, kw::Trait],
1064+
&[kw::Const, kw::Unsafe, kw::Trait],
1065+
&[kw::Const, kw::Unsafe, kw::Auto, kw::Trait],
1066+
];
1067+
// `impl(`
1068+
if self.check_keyword(exp!(Impl)) && self.look_ahead(1, |t| t == &token::OpenParen) {
1069+
// `impl(in` unambiguously introduces an `impl` restriction
1070+
if self.is_keyword_ahead(2, &[kw::In]) {
1071+
return true;
1072+
}
1073+
// `impl(crate | self | super)` + SUFFIX
1074+
if self.is_keyword_ahead(2, &[kw::Crate, kw::SelfLower, kw::Super])
1075+
&& self.look_ahead(3, |t| t == &token::CloseParen)
1076+
&& SUFFIXES.iter().any(|suffix| {
1077+
suffix.iter().enumerate().all(|(i, kw)| self.is_keyword_ahead(i + 4, &[*kw]))
1078+
})
1079+
{
1080+
return true;
1081+
}
1082+
// Recover cases like `impl(path::to::module)` + SUFFIX to suggest inserting `in`.
1083+
SUFFIXES.iter().any(|suffix| {
1084+
suffix.iter().enumerate().all(|(i, kw)| {
1085+
self.tree_look_ahead(i + 2, |t| {
1086+
if let TokenTree::Token(token, _) = t {
1087+
token.is_keyword(*kw)
1088+
} else {
1089+
false
1090+
}
1091+
})
1092+
.unwrap_or(false)
1093+
})
1094+
})
1095+
} else {
1096+
SUFFIXES.iter().any(|suffix| {
1097+
suffix.iter().enumerate().all(|(i, kw)| {
1098+
// We use `check_keyword` for the first token to include it in the expected tokens.
1099+
if i == 0 {
1100+
match *kw {
1101+
kw::Const => self.check_keyword(exp!(Const)),
1102+
kw::Unsafe => self.check_keyword(exp!(Unsafe)),
1103+
kw::Auto => self.check_keyword(exp!(Auto)),
1104+
kw::Trait => self.check_keyword(exp!(Trait)),
1105+
_ => unreachable!(),
1106+
}
1107+
} else {
1108+
self.is_keyword_ahead(i, &[*kw])
1109+
}
1110+
})
1111+
})
11151112
}
1116-
// `const unsafe auto [ impl(in? path) ]? trait`
1117-
self.is_keyword_ahead(1, &[kw::Unsafe])
1118-
&& self.is_keyword_ahead(2, &[kw::Auto])
1119-
&& self.is_trait_with_maybe_impl_restriction_in_front(3)
11201113
}
11211114

1122-
/// Parses `const? unsafe? auto? [impl(in? path)]? trait Foo { ... }` or `trait Foo = Bar;`.
1123-
///
1124-
/// FIXME(restrictions): The current keyword order follows the grammar specified in RFC 3323.
1125-
/// However, whether the restriction should be grouped closer to the visibility modifier
1126-
/// (e.g., `pub impl(crate) const unsafe auto trait`) remains an unresolved design question.
1127-
/// This ordering must be kept in sync with the logic in `check_trait_front_matter`.
1115+
/// Parses `[impl(in? path)]? const? unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
11281116
fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
1117+
let impl_restriction = self.parse_impl_restriction()?;
11291118
let constness = self.parse_constness(Case::Sensitive);
11301119
if let Const::Yes(span) = constness {
11311120
self.psess.gated_spans.gate(sym::const_trait_impl, span);
@@ -1139,8 +1128,6 @@ impl<'a> Parser<'a> {
11391128
IsAuto::No
11401129
};
11411130

1142-
let impl_restriction = self.parse_impl_restriction()?;
1143-
11441131
self.expect_keyword(exp!(Trait))?;
11451132
let ident = self.parse_ident()?;
11461133
let mut generics = self.parse_generics()?;
@@ -1181,10 +1168,10 @@ impl<'a> Parser<'a> {
11811168
generics.where_clause = self.parse_where_clause()?;
11821169
let items = self.parse_item_list(attrs, |p| p.parse_trait_item(ForceCollect::No))?;
11831170
Ok(ItemKind::Trait(Box::new(Trait {
1171+
impl_restriction,
11841172
constness,
11851173
is_auto,
11861174
safety,
1187-
impl_restriction,
11881175
ident,
11891176
generics,
11901177
bounds,
@@ -2966,7 +2953,7 @@ impl<'a> Parser<'a> {
29662953
&& !self.is_unsafe_foreign_mod()
29672954
// Rule out `async gen {` and `async gen move {`
29682955
&& !self.is_async_gen_block()
2969-
// Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl`.
2956+
// Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl`
29702957
&& !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait, kw::Impl])
29712958
)
29722959
})

0 commit comments

Comments
 (0)