Skip to content

Commit 453c505

Browse files
committed
Replace ptr hashing with ptr casting
Implementes suggeseted changes by Centril. This checks whether the memory location of the cast remains the same after atttempting to parse a postfix operator after a cast has been parsed. If the address is not the same, an illegal postfix operator was parsed. Previously the code generated a hash of the pointer, which was overly complex and inefficent. Casting the pointers and comparing them is simpler and more effcient.
1 parent f434c6e commit 453c505

File tree

1 file changed

+6
-15
lines changed

1 file changed

+6
-15
lines changed

src/librustc_parse/parser/expr.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -628,26 +628,17 @@ impl<'a> Parser<'a> {
628628
&mut self,
629629
cast_expr: P<Expr>,
630630
) -> PResult<'a, P<Expr>> {
631-
use std::collections::hash_map::DefaultHasher;
632-
use std::hash::Hasher;
633-
// Hash the memory location of expr before parsing any following postfix operators.
634-
// This will be compared with the hash of the output expression.
631+
// Save the memory location of expr before parsing any following postfix operators.
632+
// This will be compared with the memory location of the output expression.
635633
// If they different we can assume we parsed another expression because the existing expression is not reallocated.
636-
let mut before_hasher = DefaultHasher::new();
637-
std::ptr::hash(&*cast_expr, &mut before_hasher);
638-
let before_hash = before_hasher.finish();
634+
let addr_before = &*cast_expr as *const _ as usize;
639635
let span = cast_expr.span;
640636
let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
641-
642-
let mut after_hasher = DefaultHasher::new();
643-
std::ptr::hash(&*with_postfix, &mut after_hasher);
644-
let after_hash = after_hasher.finish();
637+
let changed = addr_before != &*with_postfix as *const _ as usize;
645638

646639
// Check if an illegal postfix operator has been added after the cast.
647640
// If the resulting expression is not a cast, or has a different memory location, it is an illegal postfix operator.
648-
if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _))
649-
|| after_hash != before_hash
650-
{
641+
if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) || changed {
651642
let msg = format!(
652643
"casts cannot be followed by {}",
653644
match with_postfix.kind {
@@ -661,7 +652,7 @@ impl<'a> Parser<'a> {
661652
}
662653
);
663654
let mut err = self.struct_span_err(span, &msg);
664-
// if type ascription is "likely an error", the user will already be getting a useful
655+
// If type ascription is "likely an error", the user will already be getting a useful
665656
// help message, and doesn't need a second.
666657
if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) {
667658
self.maybe_annotate_with_ascription(&mut err, false);

0 commit comments

Comments
 (0)