Skip to content

Commit a6c9d8f

Browse files
committed
Invert the keyword list to list only *no* space before delim
1 parent c70c646 commit a6c9d8f

File tree

1 file changed

+60
-38
lines changed

1 file changed

+60
-38
lines changed

src/librustdoc/clean/render_macro_matchers.rs

+60-38
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use rustc_ast_pretty::pprust::PrintState;
55
use rustc_middle::ty::TyCtxt;
66
use rustc_session::parse::ParseSess;
77
use rustc_span::source_map::FilePathMapping;
8-
use rustc_span::symbol::{kw, Symbol};
8+
use rustc_span::symbol::{kw, Ident, Symbol};
9+
use rustc_span::Span;
910

1011
/// Render a macro matcher in a format suitable for displaying to the user
1112
/// as part of an item declaration.
@@ -153,7 +154,7 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) {
153154
}
154155
(Pound, token::Not) => (false, PoundBang),
155156
(_, token::Ident(symbol, /* is_raw */ false))
156-
if !usually_needs_space_between_keyword_and_open_delim(*symbol) =>
157+
if !usually_needs_space_between_keyword_and_open_delim(*symbol, tt.span) =>
157158
{
158159
(true, Ident)
159160
}
@@ -177,42 +178,63 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) {
177178
}
178179
}
179180

180-
// This rough subset of keywords is listed here to distinguish tokens resembling
181-
// `f(0)` (no space between ident and paren) from tokens resembling `if let (0,
182-
// 0) = x` (space between ident and paren).
183-
fn usually_needs_space_between_keyword_and_open_delim(symbol: Symbol) -> bool {
181+
fn usually_needs_space_between_keyword_and_open_delim(symbol: Symbol, span: Span) -> bool {
182+
let ident = Ident { name: symbol, span };
183+
let is_keyword = ident.is_used_keyword() || ident.is_unused_keyword();
184+
if !is_keyword {
185+
// An identifier that is not a keyword usually does not need a space
186+
// before an open delim. For example: `f(0)` or `f[0]`.
187+
return false;
188+
}
189+
184190
match symbol {
185-
kw::As
186-
| kw::Box
187-
| kw::Break
188-
| kw::Const
189-
| kw::Continue
190-
| kw::Crate
191-
| kw::Else
192-
| kw::Enum
193-
| kw::Extern
194-
| kw::For
195-
| kw::If
196-
| kw::Impl
197-
| kw::In
198-
| kw::Let
199-
| kw::Loop
200-
| kw::Macro
201-
| kw::Match
202-
| kw::Mod
203-
| kw::Move
204-
| kw::Mut
205-
| kw::Ref
206-
| kw::Return
207-
| kw::Static
208-
| kw::Struct
209-
| kw::Trait
210-
| kw::Type
211-
| kw::Unsafe
212-
| kw::Use
213-
| kw::Where
214-
| kw::While
215-
| kw::Yield => true,
216-
_ => false,
191+
// No space after keywords that are syntactically an expression. For
192+
// example: a tuple struct created with `let _ = Self(0, 0)`, or if
193+
// someone has `impl Index<MyStruct> for bool` then `true[MyStruct]`.
194+
kw::False | kw::SelfLower | kw::SelfUpper | kw::True => false,
195+
196+
// No space, as in `let _: fn();`
197+
kw::Fn => false,
198+
199+
// No space, as in `pub(crate) type T;`
200+
kw::Pub => false,
201+
202+
// No space for keywords that can end an expression, as in `fut.await()`
203+
// where fut's Output type is `fn()`.
204+
kw::Await => false,
205+
206+
// Otherwise space after keyword. Some examples:
207+
//
208+
// `expr as [T; 2]`
209+
// ^
210+
// `box (tuple,)`
211+
// ^
212+
// `break (tuple,)`
213+
// ^
214+
// `type T = dyn (Fn() -> dyn Trait) + Send;`
215+
// ^
216+
// `for (tuple,) in iter {}`
217+
// ^
218+
// `if (tuple,) == v {}`
219+
// ^
220+
// `impl [T] {}`
221+
// ^
222+
// `for x in [..] {}`
223+
// ^
224+
// `let () = unit;`
225+
// ^
226+
// `match [x, y] {...}`
227+
// ^
228+
// `&mut (x as T)`
229+
// ^
230+
// `return [];`
231+
// ^
232+
// `fn f<T>() where (): Into<T>`
233+
// ^
234+
// `while (a + b).what() {}`
235+
// ^
236+
// `yield [];`
237+
// ^
238+
_ => true,
217239
}
218240
}

0 commit comments

Comments
 (0)