Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4ee338b

Browse files
committed
Implement comparison of InvisibleOrigin without PartialEq
1 parent 84a1747 commit 4ee338b

File tree

7 files changed

+66
-27
lines changed

7 files changed

+66
-27
lines changed

‎compiler/rustc_ast/src/attr/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,9 @@ impl AttrItem {
269269

270270
pub fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>> {
271271
match &self.args {
272-
AttrArgs::Delimited(args) if args.delim == Delimiter::Parenthesis => {
272+
AttrArgs::Delimited(args)
273+
if args.delim.eq_special_invisible_origin(&Delimiter::Parenthesis) =>
274+
{
273275
MetaItemKind::list_from_tokens(args.tokens.clone())
274276
}
275277
AttrArgs::Delimited(_) | AttrArgs::Eq { .. } | AttrArgs::Empty => None,

‎compiler/rustc_ast/src/token.rs

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ pub enum CommentKind {
2222
Block,
2323
}
2424

25-
// This type must not implement `Hash` due to the unusual `PartialEq` impl below.
26-
#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
25+
#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable, HashStable_Generic)]
2726
pub enum InvisibleOrigin {
2827
// From the expansion of a metavariable in a declarative macro.
2928
MetaVar(MetaVarKind),
@@ -45,20 +44,6 @@ impl InvisibleOrigin {
4544
}
4645
}
4746

48-
impl PartialEq for InvisibleOrigin {
49-
#[inline]
50-
fn eq(&self, _other: &InvisibleOrigin) -> bool {
51-
// When we had AST-based nonterminals we couldn't compare them, and the
52-
// old `Nonterminal` type had an `eq` that always returned false,
53-
// resulting in this restriction:
54-
// https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment
55-
// This `eq` emulates that behaviour. We could consider lifting this
56-
// restriction now but there are still cases involving invisible
57-
// delimiters that make it harder than it first appears.
58-
false
59-
}
60-
}
61-
6247
/// Annoyingly similar to `NonterminalKind`, but the slight differences are important.
6348
#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
6449
pub enum MetaVarKind {
@@ -114,7 +99,7 @@ impl fmt::Display for MetaVarKind {
11499
/// Describes how a sequence of token trees is delimited.
115100
/// Cannot use `proc_macro::Delimiter` directly because this
116101
/// structure should implement some additional traits.
117-
#[derive(Copy, Clone, Debug, PartialEq,Encodable, Decodable, HashStable_Generic)]
102+
#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
118103
pub enum Delimiter {
119104
/// `( ... )`
120105
Parenthesis,
@@ -130,6 +115,20 @@ pub enum Delimiter {
130115
Invisible(InvisibleOrigin),
131116
}
132117

118+
impl PartialEq for Delimiter {
119+
fn eq(&self, other: &Self) -> bool {
120+
match (self, other) {
121+
(Delimiter::Parenthesis, Delimiter::Parenthesis) => true,
122+
(Delimiter::Brace, Delimiter::Brace) => true,
123+
(Delimiter::Bracket, Delimiter::Bracket) => true,
124+
(Delimiter::Invisible(_), _) | (_, Delimiter::Invisible(_)) => {
125+
panic!("Comparing an invisible delimiter using PartialEq");
126+
}
127+
_ => false,
128+
}
129+
}
130+
}
131+
133132
impl Delimiter {
134133
// Should the parser skip these delimiters? Only happens for certain kinds
135134
// of invisible delimiters. Ideally this function will eventually disappear
@@ -142,7 +141,8 @@ impl Delimiter {
142141
}
143142
}
144143

145-
// This exists because `InvisibleOrigin`s should be compared. It is only used for assertions.
144+
// This exists because `InvisibleOrigin`s should not be compared. It is only used for
145+
// assertions.
146146
pub fn eq_ignoring_invisible_origin(&self, other: &Delimiter) -> bool {
147147
match (self, other) {
148148
(Delimiter::Parenthesis, Delimiter::Parenthesis) => true,
@@ -153,6 +153,18 @@ impl Delimiter {
153153
}
154154
}
155155

156+
/// Compare two delimiters while always considering invisible delimiters to NOT be equal
157+
/// to anything else.
158+
pub fn eq_special_invisible_origin(&self, other: &Delimiter) -> bool {
159+
match (self, other) {
160+
(Delimiter::Parenthesis, Delimiter::Parenthesis) => true,
161+
(Delimiter::Brace, Delimiter::Brace) => true,
162+
(Delimiter::Bracket, Delimiter::Bracket) => true,
163+
(Delimiter::Invisible(_), _) | (_, Delimiter::Invisible(_)) => false,
164+
_ => false,
165+
}
166+
}
167+
156168
pub fn as_open_token_kind(&self) -> TokenKind {
157169
match *self {
158170
Delimiter::Parenthesis => OpenParen,

‎compiler/rustc_ast/src/tokenstream.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ impl TokenTree {
4848
match (self, other) {
4949
(TokenTree::Token(token, _), TokenTree::Token(token2, _)) => token.kind == token2.kind,
5050
(TokenTree::Delimited(.., delim, tts), TokenTree::Delimited(.., delim2, tts2)) => {
51-
delim == delim2
51+
delim.eq_special_invisible_origin(delim2)
5252
&& tts.len() == tts2.len()
5353
&& tts.iter().zip(tts2.iter()).all(|(a, b)| a.eq_unspanned(b))
5454
}

‎compiler/rustc_ast/src/util/classify.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn expr_is_complete(e: &ast::Expr) -> bool {
7777
/// ```
7878
pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
7979
match &e.kind {
80-
MacCall(mac_call) => mac_call.args.delim != Delimiter::Brace,
80+
MacCall(mac_call) => !mac_call.args.delim.eq_special_invisible_origin(&Delimiter::Brace),
8181
_ => !expr_is_complete(e),
8282
}
8383
}
@@ -209,7 +209,8 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<TrailingBrace<'_>> {
209209
}
210210

211211
MacCall(mac) => {
212-
break (mac.args.delim == Delimiter::Brace).then_some(TrailingBrace::MacCall(mac));
212+
break (mac.args.delim.eq_special_invisible_origin(&Delimiter::Brace))
213+
.then_some(TrailingBrace::MacCall(mac));
213214
}
214215

215216
InlineAsm(_) | OffsetOf(_, _) | IncludedBytes(_) | FormatArgs(_) => {
@@ -252,7 +253,8 @@ fn type_trailing_braced_mac_call(mut ty: &ast::Ty) -> Option<&ast::MacCall> {
252253
loop {
253254
match &ty.kind {
254255
ast::TyKind::MacCall(mac) => {
255-
break (mac.args.delim == Delimiter::Brace).then_some(mac);
256+
break (mac.args.delim.eq_special_invisible_origin(&Delimiter::Brace))
257+
.then_some(mac);
256258
}
257259

258260
ast::TyKind::Ptr(mut_ty)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
795795
convert_dollar_crate: bool,
796796
span: Span,
797797
) {
798-
let cb = (delim == Delimiter::Brace).then(|| self.cbox(INDENT_UNIT));
798+
let cb =
799+
delim.eq_special_invisible_origin(&Delimiter::Brace).then(|| self.cbox(INDENT_UNIT));
799800
match header {
800801
Some(MacHeader::Path(path)) => self.print_path(path, false, 0),
801802
Some(MacHeader::Keyword(kw)) => self.word(kw),

‎compiler/rustc_expand/src/mbe/macro_parser.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use std::rc::Rc;
7777

7878
pub(crate) use NamedMatch::*;
7979
pub(crate) use ParseResult::*;
80-
use rustc_ast::token::{self, DocComment, NonterminalKind, Token};
80+
use rustc_ast::token::{self, DocComment, NonterminalKind, Token,TokenKind};
8181
use rustc_data_structures::fx::FxHashMap;
8282
use rustc_errors::ErrorGuaranteed;
8383
use rustc_lint_defs::pluralize;
@@ -397,7 +397,29 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
397397
{
398398
ident1.name == ident2.name && is_raw1 == is_raw2
399399
} else {
400-
t1.kind == t2.kind
400+
// Note: we SHOULD NOT use `t1.kind == t2.kind` here, and we should instead compare the
401+
// tokens using the special comparison function.
402+
compare_token_kind(t1.kind, t2.kind)
403+
}
404+
}
405+
406+
/// Compares two token kinds while making sure that variants containing `InvisibleOrigin` will
407+
/// never compare equal to one another.
408+
///
409+
/// When we had AST-based nonterminals we couldn't compare them, and the
410+
/// old `Nonterminal` type had an `eq` that always returned false,
411+
/// resulting in this restriction:
412+
/// https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment
413+
/// This comparison logic emulates that behaviour. We could consider lifting this
414+
/// restriction now but there are still cases involving invisible
415+
/// delimiters that make it harder than it first appears.
416+
fn compare_token_kind(t1: TokenKind, t2: TokenKind) -> bool {
417+
match (t1, t2) {
418+
(TokenKind::OpenInvisible(_), _)
419+
| (TokenKind::CloseInvisible(_), _)
420+
| (_, TokenKind::CloseInvisible(_))
421+
| (_, TokenKind::OpenInvisible(_)) => false,
422+
(a, b) => a == b,
401423
}
402424
}
403425

‎compiler/rustc_expand/src/mbe/transcribe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ pub(super) fn transcribe<'a>(
223223
FrameKind::Delimited { delim, span, mut spacing, .. } => {
224224
// Hack to force-insert a space after `]` in certain case.
225225
// See discussion of the `hex-literal` crate in #114571.
226-
if delim == Delimiter::Bracket {
226+
if delim.eq_special_invisible_origin(&Delimiter::Bracket) {
227227
spacing.close = Spacing::Alone;
228228
}
229229
if tscx.result_stack.is_empty() {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /