Skip to content

Commit 1a043b2

Browse files
committed
Replace pointer address checks in the parser
The parser used to check the address of the `P<Expr>` to determine whether a method it called had changed the value. This is undesirable for serveral reasons: - The `P::map` function allows changes while still maintaining address stability, which could break this code (although it isn't a problem right now) - Replacing it with a boolean flag is really simple - This is a Rust parser and I don't like casting pointers to integers in my Rust parser - I really dont.
1 parent 5237c4d commit 1a043b2

File tree

1 file changed

+14
-12
lines changed
  • compiler/rustc_parse/src/parser

1 file changed

+14
-12
lines changed

compiler/rustc_parse/src/parser/expr.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -829,12 +829,7 @@ impl<'a> Parser<'a> {
829829
("cast", None)
830830
};
831831

832-
// Save the memory location of expr before parsing any following postfix operators.
833-
// This will be compared with the memory location of the output expression.
834-
// If they different we can assume we parsed another expression because the existing expression is not reallocated.
835-
let addr_before = &*cast_expr as *const _ as usize;
836-
let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
837-
let changed = addr_before != &*with_postfix as *const _ as usize;
832+
let (with_postfix, changed) = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
838833

839834
// Check if an illegal postfix operator has been added after the cast.
840835
// If the resulting expression is not a cast, or has a different memory location, it is an illegal postfix operator.
@@ -959,9 +954,9 @@ impl<'a> Parser<'a> {
959954
// structure
960955
let res = self.parse_dot_or_call_expr_with_(e0, lo);
961956
if attrs.is_empty() {
962-
res
957+
res.map(|(expr, _)| expr)
963958
} else {
964-
res.map(|expr| {
959+
res.map(|(expr, _)| {
965960
expr.map(|mut expr| {
966961
attrs.extend(expr.attrs);
967962
expr.attrs = attrs;
@@ -971,7 +966,12 @@ impl<'a> Parser<'a> {
971966
}
972967
}
973968

974-
fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
969+
fn parse_dot_or_call_expr_with_(
970+
&mut self,
971+
mut e: P<Expr>,
972+
lo: Span,
973+
) -> PResult<'a, (P<Expr>, bool)> {
974+
let mut changed_expr = false;
975975
loop {
976976
let has_question = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) {
977977
// we are using noexpect here because we don't expect a `?` directly after a `return`
@@ -982,6 +982,7 @@ impl<'a> Parser<'a> {
982982
};
983983
if has_question {
984984
// `expr?`
985+
changed_expr = true;
985986
e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e));
986987
continue;
987988
}
@@ -998,13 +999,14 @@ impl<'a> Parser<'a> {
998999
continue;
9991000
}
10001001
if self.expr_is_complete(&e) {
1001-
return Ok(e);
1002+
return Ok((e, changed_expr));
10021003
}
10031004
e = match self.token.kind {
10041005
token::OpenDelim(Delimiter::Parenthesis) => self.parse_fn_call_expr(lo, e),
10051006
token::OpenDelim(Delimiter::Bracket) => self.parse_index_expr(lo, e)?,
1006-
_ => return Ok(e),
1007-
}
1007+
_ => return Ok((e, changed_expr)),
1008+
};
1009+
changed_expr = true;
10081010
}
10091011
}
10101012

0 commit comments

Comments
 (0)