Skip to content

Commit 4178059

Browse files
Reorder keywords to place restrictions next to visibility
1 parent 1b8f2e4 commit 4178059

11 files changed

Lines changed: 214 additions & 249 deletions

compiler/rustc_parse/src/parser/item.rs

Lines changed: 26 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,80 +1052,35 @@ 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+
// `impl(`
1058+
if self.check_keyword(exp!(Impl)) && self.look_ahead(1, |t| t == &token::OpenParen) {
1059+
// `impl(..) trait`
1060+
self.is_keyword_tree_ahead(2, &[kw::Trait]) ||
1061+
// `impl(..) [const | unsafe | auto] trait`
1062+
(self.is_keyword_tree_ahead(2, &[kw::Const, kw::Unsafe, kw::Auto]) && self.is_keyword_tree_ahead(3, &[kw::Trait])) ||
1063+
// `impl(..) const [unsafe | auto] trait`
1064+
(self.is_keyword_tree_ahead(2, &[kw::Const]) && self.is_keyword_tree_ahead(3, &[kw::Unsafe, kw::Auto]) && self.is_keyword_tree_ahead(4, &[kw::Trait])) ||
1065+
// `impl(..) unsafe auto trait`
1066+
(self.is_keyword_tree_ahead(2, &[kw::Unsafe]) && self.is_keyword_tree_ahead(3, &[kw::Auto]) && self.is_keyword_tree_ahead(4, &[kw::Trait])) ||
1067+
// `impl(..) const unsafe auto trait`
1068+
(self.is_keyword_tree_ahead(2, &[kw::Const]) && self.is_keyword_tree_ahead(3, &[kw::Unsafe]) && self.is_keyword_tree_ahead(4, &[kw::Auto]) && self.is_keyword_tree_ahead(5, &[kw::Trait]))
1069+
} else {
1070+
// `trait`
1071+
self.check_keyword(exp!(Trait)) ||
1072+
// `auto trait`
1073+
self.check_keyword(exp!(Auto)) && self.is_keyword_ahead(1, &[kw::Trait]) ||
1074+
// `unsafe auto? trait`
1075+
self.check_keyword(exp!(Unsafe)) && (self.is_keyword_ahead(1, &[kw::Trait]) || self.is_keyword_ahead(1, &[kw::Auto]) && self.is_keyword_ahead(2, &[kw::Trait])) ||
1076+
// `const unsafe? auto? trait`
1077+
self.check_keyword(exp!(Const)) && (self.is_keyword_ahead(1, &[kw::Trait]) || self.is_keyword_ahead(1, &[kw::Unsafe, kw::Auto]) && self.is_keyword_ahead(2, &[kw::Trait]) || self.is_keyword_ahead(1, &[kw::Unsafe]) && self.is_keyword_ahead(2, &[kw::Auto]) && self.is_keyword_ahead(3, &[kw::Trait]))
11151078
}
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)
11201079
}
11211080

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`.
1081+
/// Parses `[impl(in? path)]? const? unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
11281082
fn parse_item_trait(&mut self, attrs: &mut AttrVec, lo: Span) -> PResult<'a, ItemKind> {
1083+
let impl_restriction = self.parse_impl_restriction()?;
11291084
let constness = self.parse_constness(Case::Sensitive);
11301085
if let Const::Yes(span) = constness {
11311086
self.psess.gated_spans.gate(sym::const_trait_impl, span);
@@ -1139,8 +1094,6 @@ impl<'a> Parser<'a> {
11391094
IsAuto::No
11401095
};
11411096

1142-
let impl_restriction = self.parse_impl_restriction()?;
1143-
11441097
self.expect_keyword(exp!(Trait))?;
11451098
let ident = self.parse_ident()?;
11461099
let mut generics = self.parse_generics()?;
@@ -2966,8 +2919,8 @@ impl<'a> Parser<'a> {
29662919
&& !self.is_unsafe_foreign_mod()
29672920
// Rule out `async gen {` and `async gen move {`
29682921
&& !self.is_async_gen_block()
2969-
// Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl`.
2970-
&& !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait, kw::Impl])
2922+
// Rule out `const unsafe auto` and `const unsafe trait`
2923+
&& !self.is_keyword_ahead(2, &[kw::Auto, kw::Trait])
29712924
)
29722925
})
29732926
// `extern ABI fn`

compiler/rustc_parse/src/parser/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,18 @@ impl<'a> Parser<'a> {
12001200
self.token_cursor.curr.look_ahead(dist - 1).map(looker)
12011201
}
12021202

1203+
/// Returns whether any of the given keywords are `dist` tokens ahead over the current token tree.
1204+
pub(crate) fn is_keyword_tree_ahead(&self, dist: usize, kws: &[Symbol]) -> bool {
1205+
self.tree_look_ahead(dist, |t| {
1206+
if let TokenTree::Token(token, _) = t {
1207+
kws.iter().any(|&kw| token.is_keyword(kw))
1208+
} else {
1209+
false
1210+
}
1211+
})
1212+
.unwrap_or(false)
1213+
}
1214+
12031215
/// Returns whether any of the given keywords are `dist` tokens ahead of the current one.
12041216
pub(crate) fn is_keyword_ahead(&self, dist: usize, kws: &[Symbol]) -> bool {
12051217
self.look_ahead(dist, |t| kws.iter().any(|&kw| t.is_keyword(kw)))

tests/ui/impl-restriction/feature-gate-impl-restriction.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,32 @@ pub impl(in crate) trait BarInCrate {} //[without_gate]~ ERROR `impl` restrictio
1111

1212
mod foo {
1313
pub impl(in crate::foo) trait Baz {} //[without_gate]~ ERROR `impl` restrictions are experimental
14-
pub unsafe impl(super) trait BazUnsafeSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental
15-
pub auto impl(self) trait BazAutoSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental
16-
pub const impl(in self) trait BazConst {} //[without_gate]~ ERROR `impl` restrictions are experimental
14+
pub impl(super) unsafe trait BazUnsafeSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental
15+
pub impl(self) auto trait BazAutoSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental
16+
pub impl(in self) const trait BazConst {} //[without_gate]~ ERROR `impl` restrictions are experimental
1717

1818
mod foo_inner {
1919
pub impl(in crate::foo::foo_inner) trait Qux {} //[without_gate]~ ERROR `impl` restrictions are experimental
20-
pub unsafe auto impl(in crate::foo::foo_inner) trait QuxAutoUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental
21-
pub const unsafe impl(in crate::foo::foo_inner) trait QuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental
20+
pub impl(in crate::foo::foo_inner) unsafe auto trait QuxAutoUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental
21+
pub impl(in crate::foo::foo_inner) const unsafe trait QuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental
2222
}
2323

2424
#[cfg(false)]
2525
pub impl(crate) trait Bar {} //[without_gate]~ ERROR `impl` restrictions are experimental
2626
#[cfg(false)]
2727
pub impl(in crate) trait BarInCrate {} //[without_gate]~ ERROR `impl` restrictions are experimental
2828
#[cfg(false)]
29-
pub unsafe impl(self) trait BazUnsafeSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental
29+
pub impl(self) unsafe trait BazUnsafeSelf {} //[without_gate]~ ERROR `impl` restrictions are experimental
3030
#[cfg(false)]
31-
pub auto impl(in super) trait BazAutoSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental
31+
pub impl(in super) auto trait BazAutoSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental
3232
#[cfg(false)]
33-
pub const impl(super) trait BazConstSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental
33+
pub impl(super) const trait BazConstSuper {} //[without_gate]~ ERROR `impl` restrictions are experimental
3434

3535
#[cfg(false)]
3636
mod cfged_out_foo {
3737
pub impl(in crate::foo::cfged_out_foo) trait CfgedOutQux {} //[without_gate]~ ERROR `impl` restrictions are experimental
38-
pub unsafe auto impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxUnsafeAuto {} //[without_gate]~ ERROR `impl` restrictions are experimental
39-
pub const unsafe impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental
38+
pub impl(in crate::foo::cfged_out_foo) unsafe auto trait CfgedOutQuxUnsafeAuto {} //[without_gate]~ ERROR `impl` restrictions are experimental
39+
pub impl(in crate::foo::cfged_out_foo) const unsafe trait CfgedOutQuxConstUnsafe {} //[without_gate]~ ERROR `impl` restrictions are experimental
4040
}
4141

4242
// auto traits cannot be const, so we do not include these combinations in the test.

tests/ui/impl-restriction/feature-gate-impl-restriction.without_gate.stderr

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,30 @@ LL | pub impl(in crate::foo) trait Baz {}
2929
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3030

3131
error[E0658]: `impl` restrictions are experimental
32-
--> $DIR/feature-gate-impl-restriction.rs:14:16
32+
--> $DIR/feature-gate-impl-restriction.rs:14:9
3333
|
34-
LL | pub unsafe impl(super) trait BazUnsafeSuper {}
35-
| ^^^^^^^^^^^
34+
LL | pub impl(super) unsafe trait BazUnsafeSuper {}
35+
| ^^^^^^^^^^^
3636
|
3737
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
3838
= help: add `#![feature(impl_restriction)]` to the crate attributes to enable
3939
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
4040

4141
error[E0658]: `impl` restrictions are experimental
42-
--> $DIR/feature-gate-impl-restriction.rs:15:14
42+
--> $DIR/feature-gate-impl-restriction.rs:15:9
4343
|
44-
LL | pub auto impl(self) trait BazAutoSelf {}
45-
| ^^^^^^^^^^
44+
LL | pub impl(self) auto trait BazAutoSelf {}
45+
| ^^^^^^^^^^
4646
|
4747
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
4848
= help: add `#![feature(impl_restriction)]` to the crate attributes to enable
4949
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
5050

5151
error[E0658]: `impl` restrictions are experimental
52-
--> $DIR/feature-gate-impl-restriction.rs:16:15
52+
--> $DIR/feature-gate-impl-restriction.rs:16:9
5353
|
54-
LL | pub const impl(in self) trait BazConst {}
55-
| ^^^^^^^^^^^^^
54+
LL | pub impl(in self) const trait BazConst {}
55+
| ^^^^^^^^^^^^^
5656
|
5757
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
5858
= 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 {}
6969
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
7070

7171
error[E0658]: `impl` restrictions are experimental
72-
--> $DIR/feature-gate-impl-restriction.rs:20:25
72+
--> $DIR/feature-gate-impl-restriction.rs:20:13
7373
|
74-
LL | ... pub unsafe auto impl(in crate::foo::foo_inner) trait QuxAutoUnsafe {}
75-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
74+
LL | ... pub impl(in crate::foo::foo_inner) unsafe auto trait QuxAutoUnsafe {}
75+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7676
|
7777
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
7878
= help: add `#![feature(impl_restriction)]` to the crate attributes to enable
7979
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
8080

8181
error[E0658]: `impl` restrictions are experimental
82-
--> $DIR/feature-gate-impl-restriction.rs:21:26
82+
--> $DIR/feature-gate-impl-restriction.rs:21:13
8383
|
84-
LL | ... pub const unsafe impl(in crate::foo::foo_inner) trait QuxConstUnsafe {}
85-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
84+
LL | ... pub impl(in crate::foo::foo_inner) const unsafe trait QuxConstUnsafe {}
85+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8686
|
8787
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
8888
= help: add `#![feature(impl_restriction)]` to the crate attributes to enable
@@ -109,30 +109,30 @@ LL | pub impl(in crate) trait BarInCrate {}
109109
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
110110

111111
error[E0658]: `impl` restrictions are experimental
112-
--> $DIR/feature-gate-impl-restriction.rs:29:16
112+
--> $DIR/feature-gate-impl-restriction.rs:29:9
113113
|
114-
LL | pub unsafe impl(self) trait BazUnsafeSelf {}
115-
| ^^^^^^^^^^
114+
LL | pub impl(self) unsafe trait BazUnsafeSelf {}
115+
| ^^^^^^^^^^
116116
|
117117
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
118118
= help: add `#![feature(impl_restriction)]` to the crate attributes to enable
119119
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
120120

121121
error[E0658]: `impl` restrictions are experimental
122-
--> $DIR/feature-gate-impl-restriction.rs:31:14
122+
--> $DIR/feature-gate-impl-restriction.rs:31:9
123123
|
124-
LL | pub auto impl(in super) trait BazAutoSuper {}
125-
| ^^^^^^^^^^^^^^
124+
LL | pub impl(in super) auto trait BazAutoSuper {}
125+
| ^^^^^^^^^^^^^^
126126
|
127127
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
128128
= help: add `#![feature(impl_restriction)]` to the crate attributes to enable
129129
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
130130

131131
error[E0658]: `impl` restrictions are experimental
132-
--> $DIR/feature-gate-impl-restriction.rs:33:15
132+
--> $DIR/feature-gate-impl-restriction.rs:33:9
133133
|
134-
LL | pub const impl(super) trait BazConstSuper {}
135-
| ^^^^^^^^^^^
134+
LL | pub impl(super) const trait BazConstSuper {}
135+
| ^^^^^^^^^^^
136136
|
137137
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
138138
= 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 {}
149149
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
150150

151151
error[E0658]: `impl` restrictions are experimental
152-
--> $DIR/feature-gate-impl-restriction.rs:38:25
152+
--> $DIR/feature-gate-impl-restriction.rs:38:13
153153
|
154-
LL | ... pub unsafe auto impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxUnsafeAuto {}
155-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
154+
LL | ... pub impl(in crate::foo::cfged_out_foo) unsafe auto trait CfgedOutQuxUnsafeAuto {}
155+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
156156
|
157157
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
158158
= help: add `#![feature(impl_restriction)]` to the crate attributes to enable
159159
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
160160

161161
error[E0658]: `impl` restrictions are experimental
162-
--> $DIR/feature-gate-impl-restriction.rs:39:26
162+
--> $DIR/feature-gate-impl-restriction.rs:39:13
163163
|
164-
LL | ... pub const unsafe impl(in crate::foo::cfged_out_foo) trait CfgedOutQuxConstUnsafe {}
165-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
164+
LL | ... pub impl(in crate::foo::cfged_out_foo) const unsafe trait CfgedOutQuxConstUnsafe {}
165+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
166166
|
167167
= note: see issue #105077 <https://github.com/rust-lang/rust/issues/105077> for more information
168168
= help: add `#![feature(impl_restriction)]` to the crate attributes to enable

tests/ui/impl-restriction/recover-incorrect-impl-restriction.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
mod foo {
99
pub impl(crate::foo) trait Baz {} //~ ERROR incorrect `impl` restriction
1010
//[without_gate]~^ ERROR `impl` restrictions are experimental
11-
pub unsafe impl(crate::foo) trait BazUnsafe {} //~ ERROR incorrect `impl` restriction
11+
pub impl(crate::foo) unsafe trait BazUnsafe {} //~ ERROR incorrect `impl` restriction
1212
//[without_gate]~^ ERROR `impl` restrictions are experimental
13-
pub auto impl(crate::foo) trait BazAuto {} //~ ERROR incorrect `impl` restriction
13+
pub impl(crate::foo) auto trait BazAuto {} //~ ERROR incorrect `impl` restriction
1414
//[without_gate]~^ ERROR `impl` restrictions are experimental
15-
pub const impl(crate::foo) trait BazConst {} //~ ERROR incorrect `impl` restriction
15+
pub impl(crate::foo) const trait BazConst {} //~ ERROR incorrect `impl` restriction
1616
//[without_gate]~^ ERROR `impl` restrictions are experimental
17-
pub const unsafe impl(crate::foo) trait BazConstUnsafe {} //~ ERROR incorrect `impl` restriction
17+
pub impl(crate::foo) const unsafe trait BazConstUnsafe {} //~ ERROR incorrect `impl` restriction
1818
//[without_gate]~^ ERROR `impl` restrictions are experimental
19-
pub unsafe auto impl(crate::foo) trait BazUnsafeAuto {} //~ ERROR incorrect `impl` restriction
19+
pub impl(crate::foo) unsafe auto trait BazUnsafeAuto {} //~ ERROR incorrect `impl` restriction
2020
//[without_gate]~^ ERROR `impl` restrictions are experimental
2121
}

0 commit comments

Comments
 (0)