about summary refs log tree commit diff
path: root/src/librustc_parse
diff options
context:
space:
mode:
authorDavid <daboross@daboross.net>2020-02-24 22:11:15 -0800
committerDavid Ross <daboross@daboross.net>2020-02-29 11:05:39 -0800
commit453c5051476fab4d09f6d16bdbf37043c5c26a27 (patch)
treed90987a52bbbba22159f2dcc5ba8e1c45a6ee82f /src/librustc_parse
parentf434c6e636eda6c6c4fe167eee5b2549f8524ec7 (diff)
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.
Diffstat (limited to 'src/librustc_parse')
-rw-r--r--src/librustc_parse/parser/expr.rs21
1 files changed, 6 insertions, 15 deletions
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 12729019e9b..36ed075cebd 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -628,26 +628,17 @@ impl<'a> Parser<'a> {
         &mut self,
         cast_expr: P<Expr>,
     ) -> PResult<'a, P<Expr>> {
-        use std::collections::hash_map::DefaultHasher;
-        use std::hash::Hasher;
-        // Hash the memory location of expr before parsing any following postfix operators.
-        // This will be compared with the hash of the output expression.
+        // Save the memory location of expr before parsing any following postfix operators.
+        // This will be compared with the memory location of the output expression.
         // If they different we can assume we parsed another expression because the existing expression is not reallocated.
-        let mut before_hasher = DefaultHasher::new();
-        std::ptr::hash(&*cast_expr, &mut before_hasher);
-        let before_hash = before_hasher.finish();
+        let addr_before = &*cast_expr as *const _ as usize;
         let span = cast_expr.span;
         let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
-
-        let mut after_hasher = DefaultHasher::new();
-        std::ptr::hash(&*with_postfix, &mut after_hasher);
-        let after_hash = after_hasher.finish();
+        let changed = addr_before != &*with_postfix as *const _ as usize;
 
         // Check if an illegal postfix operator has been added after the cast.
         // If the resulting expression is not a cast, or has a different memory location, it is an illegal postfix operator.
-        if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _))
-            || after_hash != before_hash
-        {
+        if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) || changed {
             let msg = format!(
                 "casts cannot be followed by {}",
                 match with_postfix.kind {
@@ -661,7 +652,7 @@ impl<'a> Parser<'a> {
                 }
             );
             let mut err = self.struct_span_err(span, &msg);
-            // if type ascription is "likely an error", the user will already be getting a useful
+            // If type ascription is "likely an error", the user will already be getting a useful
             // help message, and doesn't need a second.
             if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) {
                 self.maybe_annotate_with_ascription(&mut err, false);