From 453c5051476fab4d09f6d16bdbf37043c5c26a27 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 24 Feb 2020 22:11:15 -0800 Subject: [PATCH] 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. --- src/librustc_parse/parser/expr.rs | 21 ++++++--------------- 1 file 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 @@ fn parse_and_disallow_postfix_after_cast( &mut self, cast_expr: P, ) -> PResult<'a, P> { - 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 @@ fn parse_and_disallow_postfix_after_cast( } ); 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);