Skip to content

Commit 06d6c62

Browse files
committed
Add newtype for raw idents
1 parent cce6a6e commit 06d6c62

File tree

24 files changed

+148
-87
lines changed

24 files changed

+148
-87
lines changed

compiler/rustc_ast/src/token.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl Lit {
107107
/// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation.
108108
pub fn from_token(token: &Token) -> Option<Lit> {
109109
match token.uninterpolate().kind {
110-
Ident(name, false) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)),
110+
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)),
111111
Literal(token_lit) => Some(token_lit),
112112
Interpolated(ref nt)
113113
if let NtExpr(expr) | NtLiteral(expr) = &nt.0
@@ -183,7 +183,7 @@ impl LitKind {
183183
}
184184
}
185185

186-
pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
186+
pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: IdentIsRaw) -> bool {
187187
let ident_token = Token::new(Ident(name, is_raw), span);
188188

189189
!ident_token.is_reserved_ident()
@@ -214,7 +214,7 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool {
214214
.contains(&name)
215215
}
216216

217-
fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool {
217+
fn ident_can_begin_type(name: Symbol, span: Span, is_raw: IdentIsRaw) -> bool {
218218
let ident_token = Token::new(Ident(name, is_raw), span);
219219

220220
!ident_token.is_reserved_ident()
@@ -223,6 +223,24 @@ fn ident_can_begin_type(name: Symbol, span: Span, is_raw: bool) -> bool {
223223
.contains(&name)
224224
}
225225

226+
#[derive(PartialEq, Encodable, Decodable, Debug, Copy, Clone, HashStable_Generic)]
227+
pub enum IdentIsRaw {
228+
No,
229+
Yes,
230+
}
231+
232+
impl From<bool> for IdentIsRaw {
233+
fn from(b: bool) -> Self {
234+
if b { Self::Yes } else { Self::No }
235+
}
236+
}
237+
238+
impl From<IdentIsRaw> for bool {
239+
fn from(is_raw: IdentIsRaw) -> bool {
240+
matches!(is_raw, IdentIsRaw::Yes)
241+
}
242+
}
243+
226244
// SAFETY: due to the `Clone` impl below, all fields of all variants other than
227245
// `Interpolated` must impl `Copy`.
228246
#[derive(PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
@@ -298,7 +316,7 @@ pub enum TokenKind {
298316
/// Do not forget about `NtIdent` when you want to match on identifiers.
299317
/// It's recommended to use `Token::(ident,uninterpolate,uninterpolated_span)` to
300318
/// treat regular and interpolated identifiers in the same way.
301-
Ident(Symbol, /* is_raw */ bool),
319+
Ident(Symbol, IdentIsRaw),
302320
/// Lifetime identifier token.
303321
/// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
304322
/// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
@@ -411,7 +429,7 @@ impl Token {
411429

412430
/// Recovers a `Token` from an `Ident`. This creates a raw identifier if necessary.
413431
pub fn from_ast_ident(ident: Ident) -> Self {
414-
Token::new(Ident(ident.name, ident.is_raw_guess()), ident.span)
432+
Token::new(Ident(ident.name, ident.is_raw_guess().into()), ident.span)
415433
}
416434

417435
/// For interpolated tokens, returns a span of the fragment to which the interpolated
@@ -567,7 +585,7 @@ impl Token {
567585
pub fn can_begin_literal_maybe_minus(&self) -> bool {
568586
match self.uninterpolate().kind {
569587
Literal(..) | BinOp(Minus) => true,
570-
Ident(name, false) if name.is_bool_lit() => true,
588+
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
571589
Interpolated(ref nt) => match &nt.0 {
572590
NtLiteral(_) => true,
573591
NtExpr(e) => match &e.kind {
@@ -602,7 +620,7 @@ impl Token {
602620

603621
/// Returns an identifier if this token is an identifier.
604622
#[inline]
605-
pub fn ident(&self) -> Option<(Ident, /* is_raw */ bool)> {
623+
pub fn ident(&self) -> Option<(Ident, IdentIsRaw)> {
606624
// We avoid using `Token::uninterpolate` here because it's slow.
607625
match &self.kind {
608626
&Ident(name, is_raw) => Some((Ident::new(name, self.span), is_raw)),
@@ -755,7 +773,7 @@ impl Token {
755773
/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
756774
pub fn is_non_raw_ident_where(&self, pred: impl FnOnce(Ident) -> bool) -> bool {
757775
match self.ident() {
758-
Some((id, false)) => pred(id),
776+
Some((id, IdentIsRaw::No)) => pred(id),
759777
_ => false,
760778
}
761779
}
@@ -806,7 +824,7 @@ impl Token {
806824
_ => return None,
807825
},
808826
SingleQuote => match joint.kind {
809-
Ident(name, false) => Lifetime(Symbol::intern(&format!("'{name}"))),
827+
Ident(name, IdentIsRaw::No) => Lifetime(Symbol::intern(&format!("'{name}"))),
810828
_ => return None,
811829
},
812830

@@ -836,7 +854,7 @@ pub enum Nonterminal {
836854
NtPat(P<ast::Pat>),
837855
NtExpr(P<ast::Expr>),
838856
NtTy(P<ast::Ty>),
839-
NtIdent(Ident, /* is_raw */ bool),
857+
NtIdent(Ident, IdentIsRaw),
840858
NtLifetime(Ident),
841859
NtLiteral(P<ast::Expr>),
842860
/// Stuff inside brackets for attributes

compiler/rustc_ast/src/tokenstream.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,7 @@ impl TokenStream {
656656
DelimSpacing::new(Spacing::JointHidden, Spacing::Alone),
657657
Delimiter::Bracket,
658658
[
659-
TokenTree::token_alone(token::Ident(sym::doc, false), span),
659+
TokenTree::token_alone(token::Ident(sym::doc, token::IdentIsRaw::No), span),
660660
TokenTree::token_alone(token::Eq, span),
661661
TokenTree::token_alone(
662662
TokenKind::lit(token::StrRaw(num_of_hashes), data, None),

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
185185

186186
// IDENT + `!`: `println!()`, but `if !x { ... }` needs a space after the `if`
187187
(Tok(Token { kind: Ident(sym, is_raw), span }, _), Tok(Token { kind: Not, .. }, _))
188-
if !Ident::new(*sym, *span).is_reserved() || *is_raw =>
188+
if !Ident::new(*sym, *span).is_reserved() || matches!(is_raw, IdentIsRaw::Yes) =>
189189
{
190190
false
191191
}
@@ -197,7 +197,7 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
197197
|| *sym == kw::Fn
198198
|| *sym == kw::SelfUpper
199199
|| *sym == kw::Pub
200-
|| *is_raw =>
200+
|| matches!(is_raw, IdentIsRaw::Yes) =>
201201
{
202202
false
203203
}
@@ -731,7 +731,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
731731
token::NtBlock(e) => self.block_to_string(e),
732732
token::NtStmt(e) => self.stmt_to_string(e),
733733
token::NtPat(e) => self.pat_to_string(e),
734-
token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(*e, *is_raw).to_string(),
734+
&token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw.into()).to_string(),
735735
token::NtLifetime(e) => e.to_string(),
736736
token::NtLiteral(e) => self.expr_to_string(e),
737737
token::NtVis(e) => self.vis_to_string(e),
@@ -795,7 +795,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
795795

796796
/* Name components */
797797
token::Ident(s, is_raw) => {
798-
IdentPrinter::new(s, is_raw, convert_dollar_crate).to_string().into()
798+
IdentPrinter::new(s, is_raw.into(), convert_dollar_crate).to_string().into()
799799
}
800800
token::Lifetime(s) => s.to_string().into(),
801801

compiler/rustc_builtin_macros/src/asm.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use ast::token::IdentIsRaw;
12
use rustc_ast as ast;
23
use rustc_ast::ptr::P;
34
use rustc_ast::token::{self, Delimiter};
@@ -416,7 +417,7 @@ fn parse_reg<'a>(
416417
) -> PResult<'a, ast::InlineAsmRegOrRegClass> {
417418
p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
418419
let result = match p.token.uninterpolate().kind {
419-
token::Ident(name, false) => ast::InlineAsmRegOrRegClass::RegClass(name),
420+
token::Ident(name, IdentIsRaw::No) => ast::InlineAsmRegOrRegClass::RegClass(name),
420421
token::Literal(token::Lit { kind: token::LitKind::Str, symbol, suffix: _ }) => {
421422
*explicit_reg = true;
422423
ast::InlineAsmRegOrRegClass::Reg(symbol)

compiler/rustc_builtin_macros/src/assert/context.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use rustc_ast::{
22
ptr::P,
3-
token,
4-
token::Delimiter,
3+
token::{self, Delimiter, IdentIsRaw},
54
tokenstream::{DelimSpan, TokenStream, TokenTree},
65
BinOpKind, BorrowKind, DelimArgs, Expr, ExprKind, ItemKind, MacCall, MethodCall, Mutability,
76
Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID,
@@ -170,7 +169,10 @@ impl<'cx, 'a> Context<'cx, 'a> {
170169
];
171170
let captures = self.capture_decls.iter().flat_map(|cap| {
172171
[
173-
TokenTree::token_joint_hidden(token::Ident(cap.ident.name, false), cap.ident.span),
172+
TokenTree::token_joint_hidden(
173+
token::Ident(cap.ident.name, IdentIsRaw::No),
174+
cap.ident.span,
175+
),
174176
TokenTree::token_alone(token::Comma, self.span),
175177
]
176178
});

compiler/rustc_expand/src/mbe/macro_check.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@
107107
use crate::errors;
108108
use crate::mbe::{KleeneToken, TokenTree};
109109

110-
use rustc_ast::token::{Delimiter, Token, TokenKind};
110+
use rustc_ast::token::{Delimiter, IdentIsRaw, Token, TokenKind};
111111
use rustc_ast::{NodeId, DUMMY_NODE_ID};
112112
use rustc_data_structures::fx::FxHashMap;
113113
use rustc_errors::{DiagnosticMessage, MultiSpan};
@@ -409,7 +409,7 @@ fn check_nested_occurrences(
409409
match (state, tt) {
410410
(
411411
NestedMacroState::Empty,
412-
&TokenTree::Token(Token { kind: TokenKind::Ident(name, false), .. }),
412+
&TokenTree::Token(Token { kind: TokenKind::Ident(name, IdentIsRaw::No), .. }),
413413
) => {
414414
if name == kw::MacroRules {
415415
state = NestedMacroState::MacroRules;

compiler/rustc_expand/src/mbe/macro_rules.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success, TtParser}
88
use crate::mbe::macro_parser::{MatchedSeq, MatchedTokenTree, MatcherLoc};
99
use crate::mbe::transcribe::transcribe;
1010

11+
use ast::token::IdentIsRaw;
1112
use rustc_ast as ast;
1213
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind, TokenKind::*};
1314
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
@@ -1302,7 +1303,9 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
13021303
match tok {
13031304
TokenTree::Token(token) => match token.kind {
13041305
FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes,
1305-
Ident(name, false) if name == kw::If || name == kw::In => IsInFollow::Yes,
1306+
Ident(name, IdentIsRaw::No) if name == kw::If || name == kw::In => {
1307+
IsInFollow::Yes
1308+
}
13061309
_ => IsInFollow::No(TOKENS),
13071310
},
13081311
_ => IsInFollow::No(TOKENS),
@@ -1313,7 +1316,9 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
13131316
match tok {
13141317
TokenTree::Token(token) => match token.kind {
13151318
FatArrow | Comma | Eq => IsInFollow::Yes,
1316-
Ident(name, false) if name == kw::If || name == kw::In => IsInFollow::Yes,
1319+
Ident(name, IdentIsRaw::No) if name == kw::If || name == kw::In => {
1320+
IsInFollow::Yes
1321+
}
13171322
_ => IsInFollow::No(TOKENS),
13181323
},
13191324
_ => IsInFollow::No(TOKENS),
@@ -1336,7 +1341,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
13361341
| BinOp(token::Shr)
13371342
| Semi
13381343
| BinOp(token::Or) => IsInFollow::Yes,
1339-
Ident(name, false) if name == kw::As || name == kw::Where => {
1344+
Ident(name, IdentIsRaw::No) if name == kw::As || name == kw::Where => {
13401345
IsInFollow::Yes
13411346
}
13421347
_ => IsInFollow::No(TOKENS),
@@ -1364,7 +1369,8 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
13641369
match tok {
13651370
TokenTree::Token(token) => match token.kind {
13661371
Comma => IsInFollow::Yes,
1367-
Ident(name, is_raw) if is_raw || name != kw::Priv => IsInFollow::Yes,
1372+
Ident(_, IdentIsRaw::Yes) => IsInFollow::Yes,
1373+
Ident(name, _) if name != kw::Priv => IsInFollow::Yes,
13681374
_ => {
13691375
if token.can_begin_type() {
13701376
IsInFollow::Yes

compiler/rustc_expand/src/mbe/metavar_expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_ast::token::{self, Delimiter};
1+
use rustc_ast::token::{self, Delimiter, IdentIsRaw};
22
use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree};
33
use rustc_ast::{LitIntType, LitKind};
44
use rustc_ast_pretty::pprust;
@@ -142,7 +142,7 @@ fn parse_ident<'sess>(
142142
if let Some(tt) = iter.next()
143143
&& let TokenTree::Token(token, _) = tt
144144
{
145-
if let Some((elem, false)) = token.ident() {
145+
if let Some((elem, IdentIsRaw::No)) = token.ident() {
146146
return Ok(elem);
147147
}
148148
let token_str = pprust::token_to_string(token);

compiler/rustc_expand/src/mbe/quoted.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::errors;
22
use crate::mbe::macro_parser::count_metavar_decls;
33
use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree};
44

5-
use rustc_ast::token::{self, Delimiter, Token};
5+
use rustc_ast::token::{self, Delimiter, IdentIsRaw, Token};
66
use rustc_ast::{tokenstream, NodeId};
77
use rustc_ast_pretty::pprust;
88
use rustc_feature::Features;
@@ -222,7 +222,7 @@ fn parse_tree<'a>(
222222
Some(tokenstream::TokenTree::Token(token, _)) if token.is_ident() => {
223223
let (ident, is_raw) = token.ident().unwrap();
224224
let span = ident.span.with_lo(span.lo());
225-
if ident.name == kw::Crate && !is_raw {
225+
if ident.name == kw::Crate && matches!(is_raw, IdentIsRaw::No) {
226226
TokenTree::token(token::Ident(kw::DollarCrate, is_raw), span)
227227
} else {
228228
TokenTree::MetaVar(span, ident)

compiler/rustc_expand/src/parse/tests.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::tests::{
22
matches_codepattern, string_to_stream, with_error_checking_parse, with_expected_parse_error,
33
};
44

5+
use ast::token::IdentIsRaw;
56
use rustc_ast::ptr::P;
67
use rustc_ast::token::{self, Delimiter, Token};
78
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
@@ -74,9 +75,12 @@ fn string_to_tts_macro() {
7475

7576
match tts {
7677
[
77-
TokenTree::Token(Token { kind: token::Ident(name_macro_rules, false), .. }, _),
78+
TokenTree::Token(
79+
Token { kind: token::Ident(name_macro_rules, IdentIsRaw::No), .. },
80+
_,
81+
),
7882
TokenTree::Token(Token { kind: token::Not, .. }, _),
79-
TokenTree::Token(Token { kind: token::Ident(name_zip, false), .. }, _),
83+
TokenTree::Token(Token { kind: token::Ident(name_zip, IdentIsRaw::No), .. }, _),
8084
TokenTree::Delimited(.., macro_delim, macro_tts),
8185
] if name_macro_rules == &kw::MacroRules && name_zip.as_str() == "zip" => {
8286
let tts = &macro_tts.trees().collect::<Vec<_>>();
@@ -90,7 +94,10 @@ fn string_to_tts_macro() {
9094
match &tts[..] {
9195
[
9296
TokenTree::Token(Token { kind: token::Dollar, .. }, _),
93-
TokenTree::Token(Token { kind: token::Ident(name, false), .. }, _),
97+
TokenTree::Token(
98+
Token { kind: token::Ident(name, IdentIsRaw::No), .. },
99+
_,
100+
),
94101
] if first_delim == &Delimiter::Parenthesis && name.as_str() == "a" => {
95102
}
96103
_ => panic!("value 3: {:?} {:?}", first_delim, first_tts),
@@ -99,7 +106,10 @@ fn string_to_tts_macro() {
99106
match &tts[..] {
100107
[
101108
TokenTree::Token(Token { kind: token::Dollar, .. }, _),
102-
TokenTree::Token(Token { kind: token::Ident(name, false), .. }, _),
109+
TokenTree::Token(
110+
Token { kind: token::Ident(name, IdentIsRaw::No), .. },
111+
_,
112+
),
103113
] if second_delim == &Delimiter::Parenthesis
104114
&& name.as_str() == "a" => {}
105115
_ => panic!("value 4: {:?} {:?}", second_delim, second_tts),
@@ -119,19 +129,28 @@ fn string_to_tts_1() {
119129
let tts = string_to_stream("fn a(b: i32) { b; }".to_string());
120130

121131
let expected = TokenStream::new(vec![
122-
TokenTree::token_alone(token::Ident(kw::Fn, false), sp(0, 2)),
123-
TokenTree::token_joint_hidden(token::Ident(Symbol::intern("a"), false), sp(3, 4)),
132+
TokenTree::token_alone(token::Ident(kw::Fn, IdentIsRaw::No), sp(0, 2)),
133+
TokenTree::token_joint_hidden(
134+
token::Ident(Symbol::intern("a"), IdentIsRaw::No),
135+
sp(3, 4),
136+
),
124137
TokenTree::Delimited(
125138
DelimSpan::from_pair(sp(4, 5), sp(11, 12)),
126139
// `JointHidden` because the `(` is followed immediately by
127140
// `b`, `Alone` because the `)` is followed by whitespace.
128141
DelimSpacing::new(Spacing::JointHidden, Spacing::Alone),
129142
Delimiter::Parenthesis,
130143
TokenStream::new(vec![
131-
TokenTree::token_joint(token::Ident(Symbol::intern("b"), false), sp(5, 6)),
144+
TokenTree::token_joint(
145+
token::Ident(Symbol::intern("b"), IdentIsRaw::No),
146+
sp(5, 6),
147+
),
132148
TokenTree::token_alone(token::Colon, sp(6, 7)),
133149
// `JointHidden` because the `i32` is immediately followed by the `)`.
134-
TokenTree::token_joint_hidden(token::Ident(sym::i32, false), sp(8, 11)),
150+
TokenTree::token_joint_hidden(
151+
token::Ident(sym::i32, IdentIsRaw::No),
152+
sp(8, 11),
153+
),
135154
])
136155
.into(),
137156
),
@@ -143,7 +162,10 @@ fn string_to_tts_1() {
143162
DelimSpacing::new(Spacing::Alone, Spacing::Alone),
144163
Delimiter::Brace,
145164
TokenStream::new(vec![
146-
TokenTree::token_joint(token::Ident(Symbol::intern("b"), false), sp(15, 16)),
165+
TokenTree::token_joint(
166+
token::Ident(Symbol::intern("b"), IdentIsRaw::No),
167+
sp(15, 16),
168+
),
147169
// `Alone` because the `;` is followed by whitespace.
148170
TokenTree::token_alone(token::Semi, sp(16, 17)),
149171
])

0 commit comments

Comments
 (0)